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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  Capybara::SpecHelper.spec '#find' do
2
3
  before do
3
4
  @session.visit('/with_html')
@@ -9,19 +10,19 @@ Capybara::SpecHelper.spec '#find' do
9
10
 
10
11
  it "should find the first element using the given locator" do
11
12
  expect(@session.find('//h1').text).to eq('This is a test')
12
- expect(@session.find("//input[@id='test_field']")[:value]).to eq('monkey')
13
+ expect(@session.find("//input[@id='test_field']").value).to eq('monkey')
13
14
  end
14
15
 
15
16
  it "should find the first element using the given locator and options" do
16
- expect(@session.find('//a', :text => 'Redirect')[:id]).to eq('red')
17
- expect(@session.find(:css, 'a', :text => 'A link came first')[:title]).to eq('twas a fine link')
17
+ expect(@session.find('//a', text: 'Redirect')[:id]).to eq('red')
18
+ expect(@session.find(:css, 'a', text: 'A link came first')[:title]).to eq('twas a fine link')
18
19
  end
19
20
 
20
21
  it "should raise an error if there are multiple matches" do
21
22
  expect { @session.find('//a') }.to raise_error(Capybara::Ambiguous)
22
23
  end
23
24
 
24
- it "should wait for asynchronous load", :requires => [:js] do
25
+ it "should wait for asynchronous load", requires: [:js] do
25
26
  @session.visit('/with_js')
26
27
  @session.click_link('Click me')
27
28
  expect(@session.find(:css, "a#has-been-clicked").text).to include('Has been clicked')
@@ -33,12 +34,12 @@ Capybara::SpecHelper.spec '#find' do
33
34
  end
34
35
  end
35
36
 
36
- context "with :wait option", :requires => [:js] do
37
+ context "with :wait option", requires: [:js] do
37
38
  it "should not wait for asynchronous load when `false` given" do
38
39
  @session.visit('/with_js')
39
40
  @session.click_link('Click me')
40
41
  expect do
41
- @session.find(:css, "a#has-been-clicked", :wait => false)
42
+ @session.find(:css, "a#has-been-clicked", wait: false)
42
43
  end.to raise_error(Capybara::ElementNotFound)
43
44
  end
44
45
 
@@ -46,18 +47,18 @@ Capybara::SpecHelper.spec '#find' do
46
47
  @session.visit('/with_js')
47
48
  @session.click_link('Slowly')
48
49
  expect do
49
- @session.find(:css, "a#slow-clicked", :wait => 0.2)
50
+ @session.find(:css, "a#slow-clicked", wait: 0.2)
50
51
  end.to raise_error(Capybara::ElementNotFound)
51
52
  end
52
53
 
53
54
  it "should find element if it appears before given wait duration" do
54
55
  @session.visit('/with_js')
55
56
  @session.click_link('Click me')
56
- expect(@session.find(:css, "a#has-been-clicked", :wait => 0.9).text).to include('Has been clicked')
57
+ expect(@session.find(:css, "a#has-been-clicked", wait: 2.0).text).to include('Has been clicked')
57
58
  end
58
59
  end
59
60
 
60
- context "with frozen time", :requires => [:js] do
61
+ context "with frozen time", requires: [:js] do
61
62
  if defined?(Process::CLOCK_MONOTONIC)
62
63
  it "will time out even if time is frozen" do
63
64
  @session.visit('/with_js')
@@ -78,7 +79,7 @@ Capybara::SpecHelper.spec '#find' do
78
79
  context "with css selectors" do
79
80
  it "should find the first element using the given locator" do
80
81
  expect(@session.find(:css, 'h1').text).to eq('This is a test')
81
- expect(@session.find(:css, "input[id='test_field']")[:value]).to eq('monkey')
82
+ expect(@session.find(:css, "input[id='test_field']").value).to eq('monkey')
82
83
  end
83
84
 
84
85
  it "should support pseudo selectors" do
@@ -89,7 +90,7 @@ Capybara::SpecHelper.spec '#find' do
89
90
  context "with xpath selectors" do
90
91
  it "should find the first element using the given locator" do
91
92
  expect(@session.find(:xpath, '//h1').text).to eq('This is a test')
92
- expect(@session.find(:xpath, "//input[@id='test_field']")[:value]).to eq('monkey')
93
+ expect(@session.find(:xpath, "//input[@id='test_field']").value).to eq('monkey')
93
94
  end
94
95
  end
95
96
 
@@ -103,11 +104,11 @@ Capybara::SpecHelper.spec '#find' do
103
104
  end
104
105
  end
105
106
 
106
- context "with custom selector with :for option" do
107
- it "should use the selector when it matches the :for option" do
107
+ context "with custom selector with custom `match` block" do
108
+ it "should use the custom selector when locator matches the block" do
108
109
  Capybara.add_selector(:beatle) do
109
110
  xpath { |num| ".//*[contains(@class, 'beatle')][#{num}]" }
110
- match { |value| value.is_a?(Fixnum) }
111
+ match { |value| value.is_a?(Integer) }
111
112
  end
112
113
  expect(@session.find(:beatle, '2').text).to eq('Paul')
113
114
  expect(@session.find(1).text).to eq('John')
@@ -125,8 +126,8 @@ Capybara::SpecHelper.spec '#find' do
125
126
  end
126
127
 
127
128
  it "should find elements that match the filter" do
128
- expect(@session.find(:beatle, 'Paul', :type => 'drummer').text).to eq('Paul')
129
- expect(@session.find(:beatle, 'Ringo', :type => 'drummer').text).to eq('Ringo')
129
+ expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
130
+ expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
130
131
  end
131
132
 
132
133
  it "ignores filter when it is not given" do
@@ -135,8 +136,8 @@ Capybara::SpecHelper.spec '#find' do
135
136
  end
136
137
 
137
138
  it "should not find elements that don't match the filter" do
138
- expect { @session.find(:beatle, 'John', :type => 'drummer') }.to raise_error(Capybara::ElementNotFound)
139
- expect { @session.find(:beatle, 'George', :type => 'drummer') }.to raise_error(Capybara::ElementNotFound)
139
+ expect { @session.find(:beatle, 'John', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
140
+ expect { @session.find(:beatle, 'George', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
140
141
  end
141
142
  end
142
143
 
@@ -144,13 +145,13 @@ Capybara::SpecHelper.spec '#find' do
144
145
  before do
145
146
  Capybara.add_selector(:beatle) do
146
147
  xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
147
- filter(:type, :default => "drummer") { |node, type| node[:class].split(/\s+/).include?(type) }
148
+ filter(:type, default: "drummer") { |node, type| node[:class].split(/\s+/).include?(type) }
148
149
  end
149
150
  end
150
151
 
151
152
  it "should find elements that match the filter" do
152
- expect(@session.find(:beatle, 'Paul', :type => 'drummer').text).to eq('Paul')
153
- expect(@session.find(:beatle, 'Ringo', :type => 'drummer').text).to eq('Ringo')
153
+ expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
154
+ expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
154
155
  end
155
156
 
156
157
  it "should use default value when filter is not given" do
@@ -159,8 +160,36 @@ Capybara::SpecHelper.spec '#find' do
159
160
  end
160
161
 
161
162
  it "should not find elements that don't match the filter" do
162
- expect { @session.find(:beatle, 'John', :type => 'drummer') }.to raise_error(Capybara::ElementNotFound)
163
- expect { @session.find(:beatle, 'George', :type => 'drummer') }.to raise_error(Capybara::ElementNotFound)
163
+ expect { @session.find(:beatle, 'John', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
164
+ expect { @session.find(:beatle, 'George', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
165
+ end
166
+ end
167
+
168
+ context "with alternate filter set" do
169
+ before do
170
+ Capybara::Selector::FilterSet.add(:value) do
171
+ filter(:with) { |node, with| node.value == with.to_s }
172
+ end
173
+
174
+ Capybara.add_selector(:id_with_field_filters) do
175
+ xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
176
+ filter_set(:field)
177
+ end
178
+ end
179
+
180
+ it "should allow use of filters from custom filter set" do
181
+ expect(@session.find(:id, 'test_field', filter_set: :value, with: 'monkey').value).to eq('monkey')
182
+ expect{ @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
183
+ end
184
+
185
+ it "should allow use of filter set from a different selector" do
186
+ expect(@session.find(:id, 'test_field', filter_set: :field, with: 'monkey').value).to eq('monkey')
187
+ expect{ @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
188
+ end
189
+
190
+ it "should allow importing of filter set into selector" do
191
+ expect(@session.find(:id_with_field_filters, 'test_field', with: 'monkey').value).to eq('monkey')
192
+ expect{ @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
164
193
  end
165
194
  end
166
195
 
@@ -168,7 +197,7 @@ Capybara::SpecHelper.spec '#find' do
168
197
  before { Capybara.default_selector = :css }
169
198
  it "should find the first element using the given locator" do
170
199
  expect(@session.find('h1').text).to eq('This is a test')
171
- expect(@session.find("input[id='test_field']")[:value]).to eq('monkey')
200
+ expect(@session.find("input[id='test_field']").value).to eq('monkey')
172
201
  end
173
202
  after { Capybara.default_selector = :xpath }
174
203
  end
@@ -176,26 +205,27 @@ Capybara::SpecHelper.spec '#find' do
176
205
  it "should raise ElementNotFound with a useful default message if nothing was found" do
177
206
  expect do
178
207
  @session.find(:xpath, '//div[@id="nosuchthing"]').to be_nil
179
- end.to raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
208
+ end.to raise_error(Capybara::ElementNotFound, "Unable to find visible xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
180
209
  end
181
210
 
182
211
  it "should accept an XPath instance" do
183
212
  @session.visit('/form')
184
- @xpath = XPath::HTML.fillable_field('First Name')
213
+ @xpath = Capybara::Selector.all[:fillable_field].call('First Name')
214
+ expect(@xpath).to be_a(::XPath::Union)
185
215
  expect(@session.find(@xpath).value).to eq('John')
186
216
  end
187
217
 
188
218
  context "with :exact option" do
189
219
  it "matches exactly when true" do
190
- expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("test_field")], :exact => true).value).to eq("monkey")
220
+ expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("test_field")], exact: true).value).to eq("monkey")
191
221
  expect do
192
- @session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("est_fiel")], :exact => true)
222
+ @session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("est_fiel")], exact: true)
193
223
  end.to raise_error(Capybara::ElementNotFound)
194
224
  end
195
225
 
196
226
  it "matches loosely when false" do
197
- expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("test_field")], :exact => false).value).to eq("monkey")
198
- expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("est_fiel")], :exact => false).value).to eq("monkey")
227
+ expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("test_field")], exact: false).value).to eq("monkey")
228
+ expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("est_fiel")], exact: false).value).to eq("monkey")
199
229
  end
200
230
 
201
231
  it "defaults to `Capybara.exact`" do
@@ -206,37 +236,43 @@ Capybara::SpecHelper.spec '#find' do
206
236
  Capybara.exact = false
207
237
  @session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is("est_fiel")])
208
238
  end
239
+
240
+ it "warns when the option has no effect" do
241
+ expect_any_instance_of(Kernel).to receive(:warn).
242
+ with('The :exact option only has an effect on queries using the XPath#is method. Using it with the query "#test_field" has no effect.')
243
+ @session.find(:css, '#test_field', exact: true)
244
+ end
209
245
  end
210
246
 
211
247
  context "with :match option" do
212
248
  context "when set to `one`" do
213
249
  it "raises an error when multiple matches exist" do
214
250
  expect do
215
- @session.find(:css, ".multiple", :match => :one)
251
+ @session.find(:css, ".multiple", match: :one)
216
252
  end.to raise_error(Capybara::Ambiguous)
217
253
  end
218
254
  it "raises an error even if there the match is exact and the others are inexact" do
219
255
  expect do
220
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], :exact => false, :match => :one)
256
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], exact: false, match: :one)
221
257
  end.to raise_error(Capybara::Ambiguous)
222
258
  end
223
259
  it "returns the element if there is only one" do
224
- expect(@session.find(:css, ".singular", :match => :one).text).to eq("singular")
260
+ expect(@session.find(:css, ".singular", match: :one).text).to eq("singular")
225
261
  end
226
262
  it "raises an error if there is no match" do
227
263
  expect do
228
- @session.find(:css, ".does-not-exist", :match => :one)
264
+ @session.find(:css, ".does-not-exist", match: :one)
229
265
  end.to raise_error(Capybara::ElementNotFound)
230
266
  end
231
267
  end
232
268
 
233
269
  context "when set to `first`" do
234
270
  it "returns the first matched element" do
235
- expect(@session.find(:css, ".multiple", :match => :first).text).to eq("multiple one")
271
+ expect(@session.find(:css, ".multiple", match: :first).text).to eq("multiple one")
236
272
  end
237
273
  it "raises an error if there is no match" do
238
274
  expect do
239
- @session.find(:css, ".does-not-exist", :match => :first)
275
+ @session.find(:css, ".does-not-exist", match: :first)
240
276
  end.to raise_error(Capybara::ElementNotFound)
241
277
  end
242
278
  end
@@ -245,25 +281,25 @@ Capybara::SpecHelper.spec '#find' do
245
281
  context "and `exact` set to `false`" do
246
282
  it "raises an error when there are multiple exact matches" do
247
283
  expect do
248
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], :match => :smart, :exact => false)
284
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], match: :smart, exact: false)
249
285
  end.to raise_error(Capybara::Ambiguous)
250
286
  end
251
287
  it "finds a single exact match when there also are inexact matches" do
252
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], :match => :smart, :exact => false)
288
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], match: :smart, exact: false)
253
289
  expect(result.text).to eq("almost singular")
254
290
  end
255
291
  it "raises an error when there are multiple inexact matches" do
256
292
  expect do
257
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], :match => :smart, :exact => false)
293
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], match: :smart, exact: false)
258
294
  end.to raise_error(Capybara::Ambiguous)
259
295
  end
260
296
  it "finds a single inexact match" do
261
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], :match => :smart, :exact => false)
297
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], match: :smart, exact: false)
262
298
  expect(result.text).to eq("almost singular but not quite")
263
299
  end
264
300
  it "raises an error if there is no match" do
265
301
  expect do
266
- @session.find(:css, ".does-not-exist", :match => :smart, :exact => false)
302
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("does-not-exist")], match: :smart, exact: false)
267
303
  end.to raise_error(Capybara::ElementNotFound)
268
304
  end
269
305
  end
@@ -271,26 +307,26 @@ Capybara::SpecHelper.spec '#find' do
271
307
  context "with `exact` set to `true`" do
272
308
  it "raises an error when there are multiple exact matches" do
273
309
  expect do
274
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], :match => :smart, :exact => true)
310
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], match: :smart, exact: true)
275
311
  end.to raise_error(Capybara::Ambiguous)
276
312
  end
277
313
  it "finds a single exact match when there also are inexact matches" do
278
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], :match => :smart, :exact => true)
314
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], match: :smart, exact: true)
279
315
  expect(result.text).to eq("almost singular")
280
316
  end
281
317
  it "raises an error when there are multiple inexact matches" do
282
318
  expect do
283
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], :match => :smart, :exact => true)
319
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], match: :smart, exact: true)
284
320
  end.to raise_error(Capybara::ElementNotFound)
285
321
  end
286
322
  it "raises an error when there is a single inexact matches" do
287
323
  expect do
288
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], :match => :smart, :exact => true)
324
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], match: :smart, exact: true)
289
325
  end.to raise_error(Capybara::ElementNotFound)
290
326
  end
291
327
  it "raises an error if there is no match" do
292
328
  expect do
293
- @session.find(:css, ".does-not-exist", :match => :smart, :exact => true)
329
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("does-not-exist")], match: :smart, exact: true)
294
330
  end.to raise_error(Capybara::ElementNotFound)
295
331
  end
296
332
  end
@@ -299,50 +335,50 @@ Capybara::SpecHelper.spec '#find' do
299
335
  context "when set to `prefer_exact`" do
300
336
  context "and `exact` set to `false`" do
301
337
  it "picks the first one when there are multiple exact matches" do
302
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], :match => :prefer_exact, :exact => false)
338
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], match: :prefer_exact, exact: false)
303
339
  expect(result.text).to eq("multiple one")
304
340
  end
305
341
  it "finds a single exact match when there also are inexact matches" do
306
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], :match => :prefer_exact, :exact => false)
342
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], match: :prefer_exact, exact: false)
307
343
  expect(result.text).to eq("almost singular")
308
344
  end
309
345
  it "picks the first one when there are multiple inexact matches" do
310
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], :match => :prefer_exact, :exact => false)
346
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], match: :prefer_exact, exact: false)
311
347
  expect(result.text).to eq("almost singular but not quite")
312
348
  end
313
349
  it "finds a single inexact match" do
314
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], :match => :prefer_exact, :exact => false)
350
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], match: :prefer_exact, exact: false)
315
351
  expect(result.text).to eq("almost singular but not quite")
316
352
  end
317
353
  it "raises an error if there is no match" do
318
354
  expect do
319
- @session.find(:css, ".does-not-exist", :match => :prefer_exact, :exact => false)
355
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("does-not-exist")], match: :prefer_exact, exact: false)
320
356
  end.to raise_error(Capybara::ElementNotFound)
321
357
  end
322
358
  end
323
359
 
324
360
  context "with `exact` set to `true`" do
325
361
  it "picks the first one when there are multiple exact matches" do
326
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], :match => :prefer_exact, :exact => true)
362
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("multiple")], match: :prefer_exact, exact: true)
327
363
  expect(result.text).to eq("multiple one")
328
364
  end
329
365
  it "finds a single exact match when there also are inexact matches" do
330
- result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], :match => :prefer_exact, :exact => true)
366
+ result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular")], match: :prefer_exact, exact: true)
331
367
  expect(result.text).to eq("almost singular")
332
368
  end
333
369
  it "raises an error if there are multiple inexact matches" do
334
370
  expect do
335
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], :match => :prefer_exact, :exact => true)
371
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singul")], match: :prefer_exact, exact: true)
336
372
  end.to raise_error(Capybara::ElementNotFound)
337
373
  end
338
374
  it "raises an error if there is a single inexact match" do
339
375
  expect do
340
- @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], :match => :prefer_exact, :exact => true)
376
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("almost_singular but")], match: :prefer_exact, exact: true)
341
377
  end.to raise_error(Capybara::ElementNotFound)
342
378
  end
343
379
  it "raises an error if there is no match" do
344
380
  expect do
345
- @session.find(:css, ".does-not-exist", :match => :prefer_exact, :exact => true)
381
+ @session.find(:xpath, XPath.descendant[XPath.attr(:class).is("does-not-exist")], match: :prefer_exact, exact: true)
346
382
  end.to raise_error(Capybara::ElementNotFound)
347
383
  end
348
384
  end
@@ -359,11 +395,15 @@ Capybara::SpecHelper.spec '#find' do
359
395
 
360
396
  it "raises an error when unknown option given" do
361
397
  expect do
362
- @session.find(:css, ".singular", :match => :schmoo)
398
+ @session.find(:css, ".singular", match: :schmoo)
363
399
  end.to raise_error(ArgumentError)
364
400
  end
365
401
  end
366
402
 
403
+ it "supports a custom filter block" do
404
+ expect(@session.find(:css, 'input'){|node| node.disabled? }[:name]).to eq('disabled_text')
405
+ end
406
+
367
407
  context "within a scope" do
368
408
  before do
369
409
  @session.visit('/with_scope')
@@ -381,4 +421,10 @@ Capybara::SpecHelper.spec '#find' do
381
421
  end
382
422
  end
383
423
  end
424
+
425
+ it "should raise if selector type is unknown" do
426
+ expect do
427
+ @session.find(:unknown, '//h1')
428
+ end.to raise_error(ArgumentError)
429
+ end
384
430
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  Capybara::SpecHelper.spec '#first' do
2
3
  before do
3
4
  @session.visit('/with_html')
@@ -5,7 +6,7 @@ Capybara::SpecHelper.spec '#first' do
5
6
 
6
7
  it "should find the first element using the given locator" do
7
8
  expect(@session.first('//h1').text).to eq('This is a test')
8
- expect(@session.first("//input[@id='test_field']")[:value]).to eq('monkey')
9
+ expect(@session.first("//input[@id='test_field']").value).to eq('monkey')
9
10
  end
10
11
 
11
12
  it "should return nil when nothing was found" do
@@ -14,21 +15,27 @@ Capybara::SpecHelper.spec '#first' do
14
15
 
15
16
  it "should accept an XPath instance" do
16
17
  @session.visit('/form')
17
- @xpath = XPath::HTML.fillable_field('First Name')
18
+ @xpath = Capybara::Selector.all[:fillable_field].call('First Name')
19
+ expect(@xpath).to be_a(::XPath::Union)
18
20
  expect(@session.first(@xpath).value).to eq('John')
19
21
  end
20
22
 
23
+ it "should warn when unused parameters are passed" do
24
+ expect_any_instance_of(Kernel).to receive(:warn).with(/Unused parameters passed.*unused text/)
25
+ @session.first(:css, '.header h2', 'unused text')
26
+ end
27
+
21
28
  context "with css selectors" do
22
29
  it "should find the first element using the given selector" do
23
30
  expect(@session.first(:css, 'h1').text).to eq('This is a test')
24
- expect(@session.first(:css, "input[id='test_field']")[:value]).to eq('monkey')
31
+ expect(@session.first(:css, "input[id='test_field']").value).to eq('monkey')
25
32
  end
26
33
  end
27
34
 
28
35
  context "with xpath selectors" do
29
36
  it "should find the first element using the given locator" do
30
37
  expect(@session.first(:xpath, '//h1').text).to eq('This is a test')
31
- expect(@session.first(:xpath, "//input[@id='test_field']")[:value]).to eq('monkey')
38
+ expect(@session.first(:xpath, "//input[@id='test_field']").value).to eq('monkey')
32
39
  end
33
40
  end
34
41
 
@@ -36,33 +43,38 @@ Capybara::SpecHelper.spec '#first' do
36
43
  before { Capybara.default_selector = :css }
37
44
  it "should find the first element using the given locator" do
38
45
  expect(@session.first('h1').text).to eq('This is a test')
39
- expect(@session.first("input[id='test_field']")[:value]).to eq('monkey')
46
+ expect(@session.first("input[id='test_field']").value).to eq('monkey')
40
47
  end
41
48
  end
42
49
 
43
50
  context "with visible filter" do
44
51
  it "should only find visible nodes when true" do
45
- expect(@session.first(:css, "a#invisible", :visible => true)).to be_nil
52
+ expect(@session.first(:css, "a#invisible", visible: true)).to be_nil
46
53
  end
47
54
 
48
55
  it "should find nodes regardless of whether they are invisible when false" do
49
- expect(@session.first(:css, "a#invisible", :visible => false)).not_to be_nil
50
- expect(@session.first(:css, "a#visible", :visible => false)).not_to be_nil
56
+ expect(@session.first(:css, "a#invisible", visible: false)).not_to be_nil
57
+ expect(@session.first(:css, "a#invisible", visible: false, text: 'hidden link')).not_to be_nil
58
+ expect(@session.first(:css, "a#visible", visible: false)).not_to be_nil
51
59
  end
52
60
 
53
61
  it "should find nodes regardless of whether they are invisible when :all" do
54
- expect(@session.first(:css, "a#invisible", :visible => :all)).not_to be_nil
55
- expect(@session.first(:css, "a#visible", :visible => :all)).not_to be_nil
62
+ expect(@session.first(:css, "a#invisible", visible: :all)).not_to be_nil
63
+ expect(@session.first(:css, "a#invisible", visible: :all, text: 'hidden link')).not_to be_nil
64
+ expect(@session.first(:css, "a#visible", visible: :all)).not_to be_nil
56
65
  end
57
66
 
58
67
  it "should find only hidden nodes when :hidden" do
59
- expect(@session.first(:css, "a#invisible", :visible => :hidden)).not_to be_nil
60
- expect(@session.first(:css, "a#visible", :visible => :hidden)).to be_nil
68
+ expect(@session.first(:css, "a#invisible", visible: :hidden)).not_to be_nil
69
+ expect(@session.first(:css, "a#invisible", visible: :hidden, text: 'hidden link')).not_to be_nil
70
+ expect(@session.first(:css, "a#invisible", visible: :hidden, text: 'not hidden link')).to be_nil
71
+ expect(@session.first(:css, "a#visible", visible: :hidden)).to be_nil
61
72
  end
62
73
 
63
74
  it "should find only visible nodes when :visible" do
64
- expect(@session.first(:css, "a#invisible", :visible => :visible)).to be_nil
65
- expect(@session.first(:css, "a#visible", :visible => :visible)).not_to be_nil
75
+ expect(@session.first(:css, "a#invisible", visible: :visible)).to be_nil
76
+ expect(@session.first(:css, "a#invisible", visible: :visible, text: 'hidden link')).to be_nil
77
+ expect(@session.first(:css, "a#visible", visible: :visible)).not_to be_nil
66
78
  end
67
79
 
68
80
  it "should default to Capybara.ignore_hidden_elements" do
@@ -99,14 +111,18 @@ Capybara::SpecHelper.spec '#first' do
99
111
 
100
112
  it "should wait for at least one match if true" do
101
113
  Capybara.wait_on_first_by_default = true
102
- @session.click_link('clickable')
103
- expect(@session.first(:css, 'a#has-been-clicked')).not_to be_nil
114
+ Capybara.using_wait_time(3) do
115
+ @session.click_link('clickable')
116
+ expect(@session.first(:css, 'a#has-been-clicked')).not_to be_nil
117
+ end
104
118
  end
105
119
 
106
120
  it "should return nil after waiting if no match" do
107
121
  Capybara.wait_on_first_by_default = true
108
- @session.click_link('clickable')
109
- expect(@session.first(:css, 'a#not-a-real-link')).to be_nil
122
+ Capybara.using_wait_time(3) do
123
+ @session.click_link('clickable')
124
+ expect(@session.first(:css, 'a#not-a-real-link')).to be_nil
125
+ end
110
126
  end
111
127
  end
112
128
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+ Capybara::SpecHelper.spec '#switch_to_frame', requires: [:frames] do
3
+ before(:each) do
4
+ @session.visit('/within_frames')
5
+ end
6
+
7
+ after(:each) do
8
+ # Ensure we clean up after the frame changes
9
+ @session.switch_to_frame(:top)
10
+ end
11
+
12
+ it "should find the div in frameOne" do
13
+ frame = @session.find(:frame, "frameOne")
14
+ @session.switch_to_frame(frame)
15
+ expect(@session.find("//*[@id='divInFrameOne']").text).to eql 'This is the text of divInFrameOne'
16
+ end
17
+
18
+ it "should find the div in FrameTwo" do
19
+ frame = @session.find(:frame, "frameTwo")
20
+ @session.switch_to_frame(frame)
21
+ expect(@session.find("//*[@id='divInFrameTwo']").text).to eql 'This is the text of divInFrameTwo'
22
+ end
23
+
24
+ it "should return to the parent frame when told to" do
25
+ frame = @session.find(:frame, "frameOne")
26
+ @session.switch_to_frame(frame)
27
+ @session.switch_to_frame(:parent)
28
+ expect(@session.find("//*[@id='divInMainWindow']").text).to eql 'This is the text for divInMainWindow'
29
+ end
30
+
31
+ it "should be able to switch to nested frames" do
32
+ frame = @session.find(:frame, "parentFrame")
33
+ @session.switch_to_frame frame
34
+ frame = @session.find(:frame, "childFrame")
35
+ @session.switch_to_frame frame
36
+ frame = @session.find(:frame, "grandchildFrame1")
37
+ @session.switch_to_frame frame
38
+ expect(@session).to have_selector(:css, '#divInFrameOne', text: 'This is the text of divInFrameOne')
39
+ end
40
+
41
+ it "should reset scope when changing frames" do
42
+ frame = @session.find(:frame, 'parentFrame')
43
+ @session.within(:css, '#divInMainWindow') do
44
+ @session.switch_to_frame(frame)
45
+ expect(@session.has_selector?(:css, "iframe#childFrame")).to be true
46
+ @session.switch_to_frame(:parent)
47
+ end
48
+ end
49
+
50
+ it "works if the frame is closed", requires: [:frames, :js] do
51
+ frame = @session.find(:frame, 'parentFrame')
52
+ @session.switch_to_frame frame
53
+ frame = @session.find(:frame, 'childFrame')
54
+ @session.switch_to_frame frame
55
+
56
+ @session.click_link 'Close Window'
57
+ @session.switch_to_frame :parent # Go back to parentFrame
58
+ expect(@session).to have_selector(:css, 'body#parentBody')
59
+ expect(@session).not_to have_selector(:css, '#childFrame')
60
+ @session.switch_to_frame :parent # Go back to top
61
+ end
62
+
63
+ it "can return to the top frame", requires: [:frames] do
64
+ frame = @session.find(:frame, "parentFrame")
65
+ @session.switch_to_frame frame
66
+ frame = @session.find(:frame, "childFrame")
67
+ @session.switch_to_frame frame
68
+ @session.switch_to_frame :top
69
+ expect(@session.find("//*[@id='divInMainWindow']").text).to eql 'This is the text for divInMainWindow'
70
+ end
71
+
72
+ it "should raise error if switching to parent unmatched inside `within` as it's nonsense" do
73
+ expect do
74
+ frame = @session.find(:frame, 'parentFrame')
75
+ @session.switch_to_frame(frame)
76
+ @session.within(:css, '#parentBody') do
77
+ @session.switch_to_frame(:parent)
78
+ end
79
+ end.to raise_error(Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's `within` block.")
80
+ end
81
+
82
+ it "should raise error if switching to top inside a `within` in a frame as it's nonsense" do
83
+ frame = @session.find(:frame, 'parentFrame')
84
+ @session.switch_to_frame(frame)
85
+ @session.within(:css, '#parentBody') do
86
+ expect do
87
+ @session.switch_to_frame(:top)
88
+ end.to raise_error(Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's `within` block.")
89
+ end
90
+ end
91
+
92
+ it "should raise error if switching to top inside a nested `within` in a frame as it's nonsense" do
93
+ frame = @session.find(:frame, 'parentFrame')
94
+ @session.switch_to_frame(frame)
95
+ @session.within(:css, '#parentBody') do
96
+ @session.switch_to_frame(@session.find(:frame, "childFrame"))
97
+ expect do
98
+ @session.switch_to_frame(:top)
99
+ end.to raise_error(Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's `within` block.")
100
+ @session.switch_to_frame(:parent)
101
+ end
102
+ end
103
+ end