capybara 2.15.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +137 -2
  3. data/README.md +36 -25
  4. data/lib/capybara/config.rb +11 -57
  5. data/lib/capybara/cucumber.rb +2 -3
  6. data/lib/capybara/driver/base.rb +19 -16
  7. data/lib/capybara/driver/node.rb +5 -4
  8. data/lib/capybara/dsl.rb +1 -0
  9. data/lib/capybara/helpers.rb +19 -29
  10. data/lib/capybara/minitest/spec.rb +16 -13
  11. data/lib/capybara/minitest.rb +140 -137
  12. data/lib/capybara/node/actions.rb +68 -89
  13. data/lib/capybara/node/base.rb +11 -18
  14. data/lib/capybara/node/document.rb +2 -2
  15. data/lib/capybara/node/document_matchers.rb +8 -8
  16. data/lib/capybara/node/element.rb +32 -42
  17. data/lib/capybara/node/finders.rb +64 -71
  18. data/lib/capybara/node/matchers.rb +50 -71
  19. data/lib/capybara/node/simple.rb +11 -17
  20. data/lib/capybara/queries/ancestor_query.rb +12 -8
  21. data/lib/capybara/queries/base_query.rb +22 -18
  22. data/lib/capybara/queries/current_path_query.rb +12 -25
  23. data/lib/capybara/queries/match_query.rb +3 -7
  24. data/lib/capybara/queries/selector_query.rb +100 -96
  25. data/lib/capybara/queries/sibling_query.rb +5 -5
  26. data/lib/capybara/queries/text_query.rb +35 -35
  27. data/lib/capybara/queries/title_query.rb +8 -11
  28. data/lib/capybara/rack_test/browser.rb +15 -18
  29. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  30. data/lib/capybara/rack_test/driver.rb +6 -10
  31. data/lib/capybara/rack_test/form.rb +52 -39
  32. data/lib/capybara/rack_test/node.rb +93 -63
  33. data/lib/capybara/rails.rb +2 -6
  34. data/lib/capybara/result.rb +22 -22
  35. data/lib/capybara/rspec/compound.rb +5 -10
  36. data/lib/capybara/rspec/features.rb +17 -48
  37. data/lib/capybara/rspec/matcher_proxies.rb +31 -15
  38. data/lib/capybara/rspec/matchers.rb +116 -58
  39. data/lib/capybara/rspec.rb +5 -10
  40. data/lib/capybara/selector/css.rb +6 -11
  41. data/lib/capybara/selector/filter.rb +1 -17
  42. data/lib/capybara/selector/filter_set.rb +18 -15
  43. data/lib/capybara/selector/filters/base.rb +7 -6
  44. data/lib/capybara/selector/filters/expression_filter.rb +6 -23
  45. data/lib/capybara/selector/filters/node_filter.rb +2 -12
  46. data/lib/capybara/selector/selector.rb +28 -34
  47. data/lib/capybara/selector.rb +129 -117
  48. data/lib/capybara/selenium/driver.rb +172 -163
  49. data/lib/capybara/selenium/node.rb +218 -104
  50. data/lib/capybara/server.rb +3 -2
  51. data/lib/capybara/session/config.rb +47 -59
  52. data/lib/capybara/session/matchers.rb +23 -14
  53. data/lib/capybara/session.rb +175 -229
  54. data/lib/capybara/spec/fixtures/no_extension +1 -0
  55. data/lib/capybara/spec/public/test.js +38 -6
  56. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
  57. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
  58. data/lib/capybara/spec/session/accept_prompt_spec.rb +30 -1
  59. data/lib/capybara/spec/session/all_spec.rb +31 -18
  60. data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
  61. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
  62. data/lib/capybara/spec/session/assert_current_path.rb +12 -11
  63. data/lib/capybara/spec/session/assert_selector.rb +1 -0
  64. data/lib/capybara/spec/session/assert_text.rb +31 -23
  65. data/lib/capybara/spec/session/assert_title.rb +13 -3
  66. data/lib/capybara/spec/session/attach_file_spec.rb +57 -29
  67. data/lib/capybara/spec/session/body_spec.rb +1 -0
  68. data/lib/capybara/spec/session/check_spec.rb +7 -6
  69. data/lib/capybara/spec/session/choose_spec.rb +5 -4
  70. data/lib/capybara/spec/session/click_button_spec.rb +24 -32
  71. data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
  72. data/lib/capybara/spec/session/click_link_spec.rb +8 -7
  73. data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
  74. data/lib/capybara/spec/session/current_url_spec.rb +19 -8
  75. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
  76. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
  77. data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
  78. data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
  79. data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
  80. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  81. data/lib/capybara/spec/session/evaluate_script_spec.rb +5 -4
  82. data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
  83. data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
  84. data/lib/capybara/spec/session/find_button_spec.rb +4 -3
  85. data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
  86. data/lib/capybara/spec/session/find_field_spec.rb +9 -15
  87. data/lib/capybara/spec/session/find_link_spec.rb +6 -5
  88. data/lib/capybara/spec/session/find_spec.rb +37 -31
  89. data/lib/capybara/spec/session/first_spec.rb +60 -33
  90. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  91. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  92. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
  93. data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
  94. data/lib/capybara/spec/session/go_back_spec.rb +1 -0
  95. data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
  96. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  97. data/lib/capybara/spec/session/has_button_spec.rb +2 -1
  98. data/lib/capybara/spec/session/has_css_spec.rb +3 -2
  99. data/lib/capybara/spec/session/has_current_path_spec.rb +49 -22
  100. data/lib/capybara/spec/session/has_field_spec.rb +4 -3
  101. data/lib/capybara/spec/session/has_link_spec.rb +5 -4
  102. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  103. data/lib/capybara/spec/session/has_select_spec.rb +32 -31
  104. data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
  105. data/lib/capybara/spec/session/has_table_spec.rb +2 -1
  106. data/lib/capybara/spec/session/has_text_spec.rb +9 -13
  107. data/lib/capybara/spec/session/has_title_spec.rb +1 -0
  108. data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
  109. data/lib/capybara/spec/session/headers.rb +2 -1
  110. data/lib/capybara/spec/session/html_spec.rb +1 -0
  111. data/lib/capybara/spec/session/node_spec.rb +107 -58
  112. data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
  113. data/lib/capybara/spec/session/refresh_spec.rb +6 -2
  114. data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
  115. data/lib/capybara/spec/session/response_code.rb +1 -0
  116. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  117. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
  118. data/lib/capybara/spec/session/save_page_spec.rb +1 -17
  119. data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
  120. data/lib/capybara/spec/session/select_spec.rb +21 -20
  121. data/lib/capybara/spec/session/selectors_spec.rb +2 -2
  122. data/lib/capybara/spec/session/sibling_spec.rb +1 -1
  123. data/lib/capybara/spec/session/text_spec.rb +17 -3
  124. data/lib/capybara/spec/session/title_spec.rb +11 -1
  125. data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
  126. data/lib/capybara/spec/session/unselect_spec.rb +7 -6
  127. data/lib/capybara/spec/session/visit_spec.rb +64 -3
  128. data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
  129. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  130. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  131. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
  132. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
  133. data/lib/capybara/spec/session/window/window_spec.rb +12 -12
  134. data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
  135. data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
  136. data/lib/capybara/spec/session/within_spec.rb +1 -0
  137. data/lib/capybara/spec/spec_helper.rb +36 -18
  138. data/lib/capybara/spec/test_app.rb +17 -9
  139. data/lib/capybara/spec/views/form.erb +7 -0
  140. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  141. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  142. data/lib/capybara/spec/views/with_hover.erb +5 -0
  143. data/lib/capybara/spec/views/with_html.erb +27 -1
  144. data/lib/capybara/spec/views/with_js.erb +11 -0
  145. data/lib/capybara/spec/views/within_frames.erb +4 -1
  146. data/lib/capybara/version.rb +2 -1
  147. data/lib/capybara/window.rb +6 -10
  148. data/lib/capybara.rb +29 -26
  149. data/spec/basic_node_spec.rb +1 -0
  150. data/spec/capybara_spec.rb +16 -69
  151. data/spec/dsl_spec.rb +5 -13
  152. data/spec/filter_set_spec.rb +5 -4
  153. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
  154. data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
  155. data/spec/minitest_spec.rb +13 -4
  156. data/spec/minitest_spec_spec.rb +12 -3
  157. data/spec/per_session_config_spec.rb +9 -8
  158. data/spec/rack_test_spec.rb +21 -20
  159. data/spec/result_spec.rb +17 -16
  160. data/spec/rspec/features_spec.rb +17 -14
  161. data/spec/rspec/scenarios_spec.rb +5 -7
  162. data/spec/rspec/shared_spec_matchers.rb +96 -99
  163. data/spec/rspec/views_spec.rb +2 -1
  164. data/spec/rspec_matchers_spec.rb +18 -2
  165. data/spec/rspec_spec.rb +11 -15
  166. data/spec/selector_spec.rb +5 -6
  167. data/spec/selenium_spec_chrome.rb +20 -11
  168. data/spec/selenium_spec_edge.rb +27 -0
  169. data/spec/selenium_spec_ie.rb +31 -0
  170. data/spec/selenium_spec_marionette.rb +38 -12
  171. data/spec/server_spec.rb +33 -33
  172. data/spec/session_spec.rb +2 -1
  173. data/spec/shared_selenium_session.rb +82 -22
  174. data/spec/spec_helper.rb +3 -6
  175. metadata +76 -81
  176. data/lib/capybara/query.rb +0 -7
  177. data/spec/selenium_spec_firefox.rb +0 -68
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
3
4
  before(:each) do
4
5
  @window = @session.current_window
@@ -90,7 +91,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
90
91
  @session.evaluate_script("[window.outerWidth || window.innerWidth, window.outerHeight || window.innerHeight]")
91
92
  end
92
93
 
93
- it 'should return size of whole window', requires: [:windows, :js] do
94
+ it 'should return size of whole window', requires: %i[windows js] do
94
95
  expect(@session.current_window.size).to eq win_size
95
96
  end
96
97
 
@@ -108,15 +109,14 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
108
109
  end
109
110
 
110
111
  describe '#resize_to' do
111
- it 'should be able to resize window', requires: [:windows, :js] do
112
+ it 'should be able to resize window', requires: %i[windows js] do
112
113
  width, height = @session.current_window.size
113
- @session.current_window.resize_to(width-100, height-100)
114
+ @session.current_window.resize_to(width - 100, height - 100)
114
115
  sleep 1
115
- expect(@session.current_window.size).to eq([width-100, height-100])
116
+ expect(@session.current_window.size).to eq([width - 100, height - 100])
116
117
  end
117
118
 
118
- it 'should stay on current window if invoked not for current window', requires: [:windows, :js] do
119
-
119
+ it 'should stay on current window if invoked not for current window', requires: %i[windows js] do
120
120
  @other_window = @session.window_opened_by do
121
121
  @session.find(:css, '#openWindow').click
122
122
  end
@@ -125,35 +125,35 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
125
125
 
126
126
  # #size returns values larger than availWidth, availHeight with Chromedriver
127
127
  @session.within_window(@other_window) do
128
- expect(@session.current_window.size).to eq([400,300])
128
+ expect(@session.current_window.size).to eq([400, 300])
129
129
  # expect(@session.evaluate_script("[window.outerWidth, window.outerHeight]")).to eq([400,300])
130
130
  end
131
131
  end
132
132
  end
133
133
 
134
134
  describe '#maximize' do
135
- it 'should be able to maximize window', requires: [:windows, :js] do
135
+ it 'should be able to maximize window', requires: %i[windows js] do
136
136
  start_width, start_height = 400, 300
137
137
  @session.current_window.resize_to(start_width, start_height)
138
138
  sleep 0.5
139
139
 
140
140
  @session.current_window.maximize
141
- sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur
141
+ sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur
142
142
 
143
143
  max_width, max_height = @session.current_window.size
144
144
 
145
- #maximize behavior is window manage dependant, so just make sure it increases in size
145
+ # maximize behavior is window manage dependant, so just make sure it increases in size
146
146
  expect(max_width).to be > start_width
147
147
  expect(max_height).to be > start_height
148
148
  end
149
149
 
150
- it 'should stay on current window if invoked not for current window', requires: [:windows, :js] do
150
+ it 'should stay on current window if invoked not for current window', requires: %i[windows js] do
151
151
  cur_window_size = @session.current_window.size
152
152
  @other_window = @session.window_opened_by do
153
153
  @session.find(:css, '#openWindow').click
154
154
  end
155
155
 
156
- @other_window.resize_to(400,300)
156
+ @other_window.resize_to(400, 300)
157
157
  sleep 0.5
158
158
  @other_window.maximize
159
159
  sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#windows', requires: [:windows] do
3
4
  before(:each) do
4
5
  @window = @session.current_window
@@ -25,8 +26,6 @@ Capybara::SpecHelper.spec '#windows', requires: [:windows] do
25
26
  titles = @session.windows.map do |window|
26
27
  @session.within_window(window) { @session.title }
27
28
  end
28
- expect(titles).to match_array([
29
- 'With Windows', 'Title of the first popup', 'Title of popup two'
30
- ])
29
+ expect(titles).to match_array(['With Windows', 'Title of the first popup', 'Title of popup two'])
31
30
  end
32
31
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
3
4
  before(:each) do
4
5
  @window = @session.current_window
@@ -19,16 +20,15 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
19
20
 
20
21
  context "with an instance of Capybara::Window" do
21
22
  it "should not invoke driver#switch_to_window when given current window" do
22
- # switch_to_window is invoked in after hook
23
- expect(@session.driver).to receive(:switch_to_window).exactly(3).times.and_call_original
23
+ allow(@session.driver).to receive(:switch_to_window).and_call_original
24
24
  @session.within_window @window do
25
25
  expect(@session.title).to eq('With Windows')
26
26
  end
27
+ expect(@session.driver).not_to have_received(:switch_to_window)
27
28
  end
28
29
 
29
30
  it "should be able to switch to another window" do
30
31
  window = (@session.windows - [@window]).first
31
- expect(@session.driver).to receive(:switch_to_window).exactly(5).times.and_call_original
32
32
  @session.within_window window do
33
33
  expect(@session).to have_title(/Title of the first popup|Title of popup two/)
34
34
  end
@@ -38,8 +38,8 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
38
38
  it "returns value from the block" do
39
39
  window = (@session.windows - [@window]).first
40
40
  value = @session.within_window window do
41
- 43252003274489856000
42
- end
41
+ 43252003274489856000
42
+ end
43
43
  expect(value).to eq(43252003274489856000)
44
44
  end
45
45
 
@@ -57,7 +57,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
57
57
  expect(@session.send(:scopes)).to eq([nil])
58
58
  end
59
59
 
60
- it "should leave correct scopes after execution in case of error", requires: [:windows, :frames] do
60
+ it "should leave correct scopes after execution in case of error", requires: %i[windows frames] do
61
61
  window = (@session.windows - [@window]).first
62
62
  expect do
63
63
  @session.within_frame 'frameOne' do
@@ -87,25 +87,25 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
87
87
 
88
88
  context "with lambda" do
89
89
  it "should find the div in another window" do
90
- @session.within_window(->{ @session.title == 'Title of the first popup'}) do
90
+ @session.within_window(-> { @session.title == 'Title of the first popup' }) do
91
91
  expect(@session).to have_css('#divInPopupOne')
92
92
  end
93
93
  end
94
94
 
95
95
  it "should find divs in both windows" do
96
- @session.within_window(->{ @session.title == 'Title of popup two'}) do
96
+ @session.within_window(-> { @session.title == 'Title of popup two' }) do
97
97
  expect(@session).to have_css('#divInPopupTwo')
98
98
  end
99
- @session.within_window(->{ @session.title == 'Title of the first popup'}) do
99
+ @session.within_window(-> { @session.title == 'Title of the first popup' }) do
100
100
  expect(@session).to have_css('#divInPopupOne')
101
101
  end
102
102
  expect(@session.title).to eq('With Windows')
103
103
  end
104
104
 
105
105
  it "should be able to nest within_window" do
106
- @session.within_window(->{ @session.title == 'Title of popup two'}) do
106
+ @session.within_window(-> { @session.title == 'Title of popup two' }) do
107
107
  expect(@session).to have_css('#divInPopupTwo')
108
- @session.within_window(->{ @session.title == 'Title of the first popup'}) do
108
+ @session.within_window(-> { @session.title == 'Title of the first popup' }) do
109
109
  expect(@session).to have_css('#divInPopupOne')
110
110
  end
111
111
  expect(@session).to have_css('#divInPopupTwo')
@@ -119,7 +119,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
119
119
  it "should work inside a normal scope" do
120
120
  expect(@session).to have_css('#openWindow')
121
121
  @session.within(:css, '#scope') do
122
- @session.within_window(->{ @session.title == 'Title of the first popup'}) do
122
+ @session.within_window(-> { @session.title == 'Title of the first popup' }) do
123
123
  expect(@session).to have_css('#divInPopupOne')
124
124
  end
125
125
  expect(@session).to have_content('My scoped content')
@@ -129,7 +129,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
129
129
 
130
130
  it "should raise error if window wasn't found" do
131
131
  expect do
132
- @session.within_window(->{ @session.title == 'Invalid title'}) do
132
+ @session.within_window(-> { @session.title == 'Invalid title' }) do
133
133
  expect(@session).to have_css('#divInPopupOne')
134
134
  end
135
135
  end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda")
@@ -139,15 +139,13 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
139
139
  end
140
140
 
141
141
  it "returns value from the block" do
142
- value = @session.within_window(->{ @session.title == 'Title of popup two'}) do
143
- 42
144
- end
142
+ value = @session.within_window(-> { @session.title == 'Title of popup two' }) { 42 }
145
143
  expect(value).to eq(42)
146
144
  end
147
145
 
148
146
  it "should switch back if exception was raised inside block" do
149
147
  expect do
150
- @session.within_window(->{ @session.title == 'Title of popup two'}) do
148
+ @session.within_window(-> { @session.title == 'Title of popup two' }) do
151
149
  raise 'some error'
152
150
  end
153
151
  end.to raise_error(StandardError, 'some error')
@@ -155,58 +153,4 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
155
153
  expect(@session.send(:scopes)).to eq([nil])
156
154
  end
157
155
  end
158
-
159
- context "with string" do
160
- it "should warn" do
161
- expect(@session).to receive(:warn).with(/DEPRECATION WARNING/).and_call_original
162
- @session.within_window('firstPopup') {}
163
- end
164
-
165
- it "should find window by handle" do
166
- window = (@session.windows - [@window]).first
167
- @session.within_window window.handle do
168
- expect(@session).to have_title(/Title of the first popup|Title of popup two/)
169
- end
170
- end
171
-
172
- it "should find the div in firstPopup" do
173
- @session.within_window("firstPopup") do
174
- expect(@session.find("//*[@id='divInPopupOne']").text).to eq 'This is the text of divInPopupOne'
175
- end
176
- end
177
- it "should find the div in secondPopup" do
178
- @session.within_window("secondPopup") do
179
- expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo'
180
- end
181
- end
182
- it "should find the divs in both popups" do
183
- @session.within_window("secondPopup") do
184
- expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo'
185
- end
186
- @session.within_window("firstPopup") do
187
- expect(@session.find("//*[@id='divInPopupOne']").text).to eq 'This is the text of divInPopupOne'
188
- end
189
- end
190
- it "should find the div in the main window after finding a div in a popup" do
191
- @session.within_window("secondPopup") do
192
- expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo'
193
- end
194
- expect(@session.find("//*[@id='doesNotOpenWindows']").text).to eq 'Does not open windows'
195
- end
196
- it "should reset scope when switching windows" do
197
- @session.within(:css, '#doesNotOpenWindows') do
198
- @session.within_window("secondPopup") do
199
- expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo'
200
- end
201
- end
202
- end
203
- it "should switch back if exception was raised inside block" do
204
- expect do
205
- @session.within_window('secondPopup') do
206
- raise 'some error'
207
- end
208
- end.to raise_error(StandardError, 'some error')
209
- expect(@session.current_window).to eq(@window)
210
- end
211
- end
212
156
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#within' do
3
4
  before do
4
5
  @session.visit('/with_scope')
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "rspec"
3
4
  require "rspec/expectations"
4
5
  require "capybara"
@@ -6,15 +7,6 @@ require "capybara/rspec" # Required here instead of in rspec_spec to avoid RSpec
6
7
  require "capybara/spec/test_app"
7
8
  require "nokogiri"
8
9
 
9
- # Alias be_truthy/be_falsey if not already defined to be able to use in RSpec 2 and 3
10
- unless RSpec::Matchers.method_defined?(:be_truthy)
11
- RSpec::Matchers.module_eval do
12
- alias be_truthy be_true
13
- alias be_falsey be_false
14
- alias be_falsy be_false
15
- end
16
- end
17
-
18
10
  module Capybara
19
11
  module SpecHelper
20
12
  class << self
@@ -33,11 +25,9 @@ module Capybara
33
25
  Capybara.default_max_wait_time = 1
34
26
  Capybara.ignore_hidden_elements = true
35
27
  Capybara.exact = false
36
- Capybara.exact_options = false
37
28
  Capybara.raise_server_errors = true
38
29
  Capybara.visible_text_only = false
39
30
  Capybara.match = :smart
40
- Capybara.wait_on_first_by_default = false
41
31
  Capybara.enable_aria_label = false
42
32
  reset_threadsafe
43
33
  end
@@ -52,12 +42,12 @@ module Capybara
52
42
  end
53
43
  end
54
44
 
55
- def spec(name, options={}, &block)
45
+ def spec(name, *options, &block)
56
46
  @specs ||= []
57
47
  @specs << [name, options, block]
58
48
  end
59
49
 
60
- def run_specs(session, name, options={})
50
+ def run_specs(session, name, **options)
61
51
  specs = @specs
62
52
  RSpec.describe Capybara::Session, name, options do
63
53
  include Capybara::SpecHelper
@@ -78,8 +68,12 @@ module Capybara
78
68
  SpecHelper.reset_threadsafe(false, @session)
79
69
  end
80
70
 
71
+ before :each, :exact_false do
72
+ Capybara.exact = false
73
+ end
74
+
81
75
  specs.each do |spec_name, spec_options, block|
82
- describe spec_name, spec_options do
76
+ describe spec_name, *spec_options do
83
77
  class_eval(&block)
84
78
  end
85
79
  end
@@ -92,7 +86,7 @@ module Capybara
92
86
  session = session.current_session if session.respond_to?(:current_session)
93
87
  session.instance_variable_set(:@config, nil) if session
94
88
  end
95
- end # class << self
89
+ end
96
90
 
97
91
  def silence_stream(stream)
98
92
  old_stream = stream.dup
@@ -117,11 +111,35 @@ module Capybara
117
111
  end
118
112
 
119
113
  def marionette?(session)
120
- session.driver.respond_to?(:marionette?, true) && session.driver.send(:marionette?)
114
+ session.respond_to?(:driver) && session.driver.respond_to?(:marionette?, true) && session.driver.send(:marionette?)
115
+ end
116
+
117
+ def marionette_lt?(version, session)
118
+ marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f < version)
119
+ end
120
+
121
+ def marionette_gte?(version, session)
122
+ marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f >= version)
123
+ end
124
+
125
+ def chrome?(session)
126
+ session.respond_to?(:driver) && session.driver.respond_to?(:chrome?, true) && session.driver.send(:chrome?)
127
+ end
128
+
129
+ def chrome_lt?(version, session)
130
+ chrome?(session) && (session.driver.browser.capabilities[:version].to_f < version)
131
+ end
132
+
133
+ def chrome_gte?(version, session)
134
+ chrome?(session) && (session.driver.browser.capabilities[:version].to_f >= version)
135
+ end
136
+
137
+ def edge?(session)
138
+ session.respond_to?(:driver) && session.driver.respond_to?(:edge?, true) && session.driver.send(:edge?)
121
139
  end
122
140
 
123
- def rspec2?
124
- !defined?(::RSpec::Expectations::Version) || (Gem::Version.new(RSpec::Expectations::Version::STRING) < Gem::Version.new('3.0'))
141
+ def ie?(session)
142
+ session.respond_to?(:driver) && session.driver.respond_to?(:ie?, true) && session.driver.send(:ie?)
125
143
  end
126
144
  end
127
145
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'sinatra/base'
3
4
  require 'tilt/erb'
4
5
  require 'rack'
@@ -21,7 +22,7 @@ class TestApp < Sinatra::Base
21
22
  # Also check lib/capybara/spec/views/*.erb for pages not listed here
22
23
 
23
24
  get '/' do
24
- response.set_cookie('capybara', { value: 'root cookie', domain: request.host, path: request.path} )
25
+ response.set_cookie('capybara', value: 'root cookie', domain: request.host, path: request.path)
25
26
  'Hello world! <a href="with_html">Relative</a>'
26
27
  end
27
28
 
@@ -38,8 +39,8 @@ class TestApp < Sinatra::Base
38
39
  end
39
40
 
40
41
  get '/referer_base' do
41
- '<a href="/get_referer">direct link</a>' +
42
- '<a href="/redirect_to_get_referer">link via redirect</a>' +
42
+ '<a href="/get_referer">direct link</a>' \
43
+ '<a href="/redirect_to_get_referer">link via redirect</a>' \
43
44
  '<form action="/get_referer" method="get"><input type="submit"></form>'
44
45
  end
45
46
 
@@ -69,7 +70,7 @@ class TestApp < Sinatra::Base
69
70
  end
70
71
 
71
72
  get '/with-quotes' do
72
- %q{"No," he said, "you can't do that."}
73
+ %q("No," he said, "you can't do that.")
73
74
  end
74
75
 
75
76
  get '/form/get' do
@@ -143,13 +144,22 @@ class TestApp < Sinatra::Base
143
144
  erb :with_html, locals: { referrer: request.referrer }
144
145
  end
145
146
 
147
+ get '/with_title' do
148
+ <<-HTML
149
+ <title>#{params[:title] || 'Test Title'}</title>
150
+ <body>
151
+ <svg><title>abcdefg</title></svg>
152
+ </body>
153
+ HTML
154
+ end
155
+
146
156
  get '/:view' do |view|
147
157
  erb view.to_sym, locals: { referrer: request.referrer }
148
158
  end
149
159
 
150
160
  post '/form' do
151
161
  @@form_post_count += 1
152
- '<pre id="results">' + params[:form].merge({"post_count" => @@form_post_count}).to_yaml + '</pre>'
162
+ '<pre id="results">' + params[:form].merge("post_count" => @@form_post_count).to_yaml + '</pre>'
153
163
  end
154
164
 
155
165
  post '/upload_empty' do
@@ -173,7 +183,7 @@ class TestApp < Sinatra::Base
173
183
 
174
184
  post '/upload_multiple' do
175
185
  begin
176
- buffer = ["#{params[:form][:multiple_documents].size}"]
186
+ buffer = [params[:form][:multiple_documents].size.to_s]
177
187
  params[:form][:multiple_documents].each do |doc|
178
188
  buffer << "Content-type: #{doc[:type]}"
179
189
  buffer << "File content: #{doc[:tempfile].read}"
@@ -185,6 +195,4 @@ class TestApp < Sinatra::Base
185
195
  end
186
196
  end
187
197
 
188
- if __FILE__ == $0
189
- Rack::Handler::WEBrick.run TestApp, Port: 8070
190
- end
198
+ Rack::Handler::Puma.run TestApp, Port: 8070 if $PROGRAM_NAME == __FILE__
@@ -186,6 +186,7 @@ New line after and before textarea tag
186
186
  <input type="checkbox" value="pagani" name="form[cars][]" id="form_cars_pagani" style="position: absolute; left: -9999px"/>
187
187
  <label for="form_cars_pagani">Pagani</label>
188
188
  <input type="checkbox" value="ariel" name="form[cars][]" id="form_cars_ariel" style="display: none"/>
189
+ <input type="checkbox" value="porsche" name="form[cars][]" id="form_cars_porsche" checked="checked" style="display: none"/>
189
190
  <label>
190
191
  McLaren
191
192
  <input type="checkbox" value="mclaren" name="form[cars][]" id="form_cars_mclaren" style="display: none"/>
@@ -425,6 +426,12 @@ New line after and before textarea tag
425
426
  <input type="button" disabled="disabled" value="Disabled button"/>
426
427
  </p>
427
428
 
429
+ <p>
430
+ <input type="date" name="form[date]" id="form_date"/>
431
+ <input type="time" name="form[time]" id="form_time"/>
432
+ <input type="datetime-local" name="form[datetime]" id="form_datetime">
433
+ </p>
434
+
428
435
  <p>
429
436
  <input id="readonly" name="form[readonly_test]" readonly/>
430
437
  <input id="not_readonly" name="form[readonly_test]" />
@@ -0,0 +1,10 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
2
+ <body>
3
+ <div>
4
+ Initial alert page
5
+ </div>
6
+ <script>
7
+ window.alert("Initial alert");
8
+ </script>
9
+ </body>
10
+ </html>
@@ -0,0 +1,17 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ header { height: 45px; position: fixed; top: 0; background-color: red; width: 100%;}
5
+ footer { height: 45px; position: fixed; bottom: 0; background-color: red; width: 100%;}
6
+ #main { margin: 45px;}
7
+ #tall { display: block; height: 2000px;}
8
+ </style>
9
+ </head>
10
+ <body>
11
+ <header>My headers</header>
12
+ <div id="main">
13
+ <div id="tall">A tall block</div>
14
+ <a href="/">Go to root</a>
15
+ </div>
16
+ <footer>My footer</footer>
17
+ </body>
@@ -14,5 +14,10 @@
14
14
  Some text here so the wrapper has size
15
15
  <div class="hidden_until_hover">Here I am</div>
16
16
  </div>
17
+ <div style="display: block; height: 1000px; width: 100%"></div>
18
+ <div class="wrapper scroll_needed" >
19
+ Some text here so the wrapper has size
20
+ <div class="hidden_until_hover">Here I am</div>
21
+ </div>
17
22
  </body>
18
23
  </html>
@@ -122,6 +122,10 @@ banana</textarea>
122
122
  <a id="link_blank_href" href="">Blank href</a>
123
123
  </div>
124
124
 
125
+ <div id="uppercase" style="text-transform: uppercase;">
126
+ text here
127
+ </div>
128
+
125
129
  <div id="ancestor3">
126
130
  Ancestor
127
131
  <div id="ancestor2">
@@ -146,4 +150,26 @@ banana</textarea>
146
150
  <div data-pre=true>Pre Sibling</div>
147
151
  <div data-post=true>Post Sibling</div>
148
152
  </div>
149
- </div>
153
+ </div>
154
+
155
+ <div id='1escape.me' class="2escape">needs escaping</div>
156
+
157
+ <div id="normalized">
158
+ Some text<div>More text</div>
159
+ <div> And more text</div>
160
+ Even more &nbsp;&nbsp; text
161
+
162
+ on multiple lines
163
+ </div>
164
+
165
+ <div id="non_visible_normalized" style="display: none">
166
+ Some text<div>More text</div>
167
+ <div> And more text</div>
168
+ Even more &nbsp;&nbsp; text
169
+
170
+ on multiple lines
171
+ </div>
172
+
173
+ <div id="ws">
174
+ &#x20;&#x1680;&#x2000;&#x2001;&#x2002; &#x2003;&#x2004;&nbsp;&#x2005; &#x2006;&#x2007;&#x2008;&#x2009;&#x200A;&#x202F;&#x205F;&#x3000;
175
+ </div>
@@ -96,6 +96,10 @@
96
96
  <a href="#" id="open-prompt">Open prompt</a>
97
97
  </p>
98
98
 
99
+ <p>
100
+ <a href="#" id="open-prompt-with-default">Open defaulted prompt</a>
101
+ </p>
102
+
99
103
  <p>
100
104
  <input id="disable-on-click"/>
101
105
  </p>
@@ -117,6 +121,13 @@
117
121
  <input type="file" id="hidden_file" style="opacity:0; display: none;">
118
122
  </p>
119
123
 
124
+ <div id="drag_scroll">
125
+ <p>This is a draggable element.</p>
126
+ </div>
127
+ <div id="drop_scroll">
128
+ <p>It should be dropped here.</p>
129
+ </div>
130
+
120
131
  <script type="text/javascript">
121
132
  // a javascript comment
122
133
  var aVar = 123;
@@ -4,7 +4,10 @@
4
4
  <title>With Frames</title>
5
5
  </head>
6
6
  <body>
7
- <div id="divInMainWindow">This is the text for divInMainWindow</div>
7
+ <div id="divInMainWindow">
8
+ This is the text for divInMainWindow
9
+ <iframe src="/frame_parent" id="innerParentFrame"></iframe>
10
+ </div>
8
11
  <iframe src="/frame_one" id="frameOne" name="my frame one"></iframe>
9
12
  <iframe src="/frame_two" id="frameTwo"></iframe>
10
13
  <iframe src="/frame_parent" id="parentFrame"></iframe>
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
- VERSION = '2.15.0'
4
+ VERSION = '3.0.0'.freeze
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
4
  ##
4
5
  # The Window class represents a browser window.
@@ -101,7 +102,7 @@ module Capybara
101
102
  end
102
103
 
103
104
  def eql?(other)
104
- other.kind_of?(self.class) && @session == other.session && @handle == other.handle
105
+ other.is_a?(self.class) && @session == other.session && @handle == other.handle
105
106
  end
106
107
  alias_method :==, :eql?
107
108
 
@@ -113,9 +114,9 @@ module Capybara
113
114
  "#<Window @handle=#{@handle.inspect}>"
114
115
  end
115
116
 
116
- private
117
+ private
117
118
 
118
- def wait_for_stable_size(seconds=session.config.default_max_wait_time)
119
+ def wait_for_stable_size(seconds = session.config.default_max_wait_time)
119
120
  res = yield if block_given?
120
121
  prev_size = size
121
122
  start_time = Capybara::Helpers.monotonic_time
@@ -125,16 +126,11 @@ module Capybara
125
126
  return res if cur_size == prev_size
126
127
  prev_size = cur_size
127
128
  end while (Capybara::Helpers.monotonic_time - start_time) < seconds
128
- #TODO raise error in 3.0
129
- #raise Capybara::WindowError, "Window size not stable."
130
- warn "Window size not stable in #{seconds} seconds. This will raise an exception in a future version of Capybara"
131
- return res
129
+ raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
132
130
  end
133
131
 
134
132
  def raise_unless_current(what)
135
- unless current?
136
- raise Capybara::WindowError, "#{what} not current window is not possible."
137
- end
133
+ raise Capybara::WindowError, "#{what} not current window is not possible." unless current?
138
134
  end
139
135
  end
140
136
  end