capybara 3.35.2 → 3.37.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +59 -4
  3. data/README.md +5 -1
  4. data/lib/capybara/config.rb +16 -4
  5. data/lib/capybara/driver/base.rb +4 -0
  6. data/lib/capybara/driver/node.rb +5 -1
  7. data/lib/capybara/dsl.rb +4 -10
  8. data/lib/capybara/helpers.rb +2 -11
  9. data/lib/capybara/minitest/spec.rb +2 -2
  10. data/lib/capybara/node/actions.rb +10 -5
  11. data/lib/capybara/node/document.rb +2 -2
  12. data/lib/capybara/node/element.rb +13 -2
  13. data/lib/capybara/node/finders.rb +2 -2
  14. data/lib/capybara/node/simple.rb +5 -1
  15. data/lib/capybara/queries/active_element_query.rb +18 -0
  16. data/lib/capybara/queries/ancestor_query.rb +2 -1
  17. data/lib/capybara/queries/current_path_query.rb +1 -1
  18. data/lib/capybara/queries/selector_query.rb +34 -8
  19. data/lib/capybara/queries/sibling_query.rb +2 -1
  20. data/lib/capybara/rack_test/browser.rb +41 -6
  21. data/lib/capybara/rack_test/driver.rb +4 -4
  22. data/lib/capybara/rack_test/node.rb +10 -7
  23. data/lib/capybara/registration_container.rb +0 -3
  24. data/lib/capybara/registrations/drivers.rb +3 -3
  25. data/lib/capybara/rspec/matcher_proxies.rb +3 -3
  26. data/lib/capybara/rspec/matchers/have_selector.rb +5 -5
  27. data/lib/capybara/rspec/matchers.rb +14 -14
  28. data/lib/capybara/selector/builders/css_builder.rb +1 -1
  29. data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
  30. data/lib/capybara/selector/css.rb +1 -1
  31. data/lib/capybara/selector/definition/button.rb +9 -4
  32. data/lib/capybara/selector/definition/checkbox.rb +1 -1
  33. data/lib/capybara/selector/definition/file_field.rb +1 -1
  34. data/lib/capybara/selector/definition/fillable_field.rb +1 -1
  35. data/lib/capybara/selector/definition/radio_button.rb +1 -1
  36. data/lib/capybara/selector/definition.rb +3 -1
  37. data/lib/capybara/selector/filter_set.rb +4 -6
  38. data/lib/capybara/selector.rb +1 -0
  39. data/lib/capybara/selenium/driver.rb +25 -11
  40. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
  41. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +1 -1
  42. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
  43. data/lib/capybara/selenium/node.rb +22 -8
  44. data/lib/capybara/selenium/nodes/chrome_node.rb +1 -1
  45. data/lib/capybara/selenium/nodes/edge_node.rb +1 -1
  46. data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
  47. data/lib/capybara/selenium/nodes/safari_node.rb +2 -2
  48. data/lib/capybara/server/animation_disabler.rb +35 -17
  49. data/lib/capybara/session/config.rb +1 -1
  50. data/lib/capybara/session.rb +20 -23
  51. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  52. data/lib/capybara/spec/session/all_spec.rb +9 -13
  53. data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
  54. data/lib/capybara/spec/session/check_spec.rb +9 -0
  55. data/lib/capybara/spec/session/choose_spec.rb +6 -0
  56. data/lib/capybara/spec/session/has_any_selectors_spec.rb +4 -0
  57. data/lib/capybara/spec/session/has_button_spec.rb +24 -0
  58. data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
  59. data/lib/capybara/spec/session/has_field_spec.rb +25 -1
  60. data/lib/capybara/spec/session/has_link_spec.rb +24 -0
  61. data/lib/capybara/spec/session/has_select_spec.rb +4 -4
  62. data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
  63. data/lib/capybara/spec/session/has_text_spec.rb +2 -6
  64. data/lib/capybara/spec/session/node_spec.rb +43 -1
  65. data/lib/capybara/spec/session/scroll_spec.rb +4 -4
  66. data/lib/capybara/spec/session/visit_spec.rb +14 -0
  67. data/lib/capybara/spec/session/window/window_spec.rb +1 -1
  68. data/lib/capybara/spec/spec_helper.rb +4 -3
  69. data/lib/capybara/spec/test_app.rb +50 -8
  70. data/lib/capybara/spec/views/animated.erb +1 -1
  71. data/lib/capybara/spec/views/form.erb +11 -3
  72. data/lib/capybara/spec/views/frame_child.erb +1 -1
  73. data/lib/capybara/spec/views/frame_one.erb +1 -1
  74. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  75. data/lib/capybara/spec/views/frame_two.erb +1 -1
  76. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  77. data/lib/capybara/spec/views/layout.erb +10 -0
  78. data/lib/capybara/spec/views/obscured.erb +1 -1
  79. data/lib/capybara/spec/views/offset.erb +2 -1
  80. data/lib/capybara/spec/views/path.erb +2 -2
  81. data/lib/capybara/spec/views/popup_one.erb +1 -1
  82. data/lib/capybara/spec/views/popup_two.erb +1 -1
  83. data/lib/capybara/spec/views/react.erb +2 -2
  84. data/lib/capybara/spec/views/scroll.erb +2 -1
  85. data/lib/capybara/spec/views/spatial.erb +1 -1
  86. data/lib/capybara/spec/views/with_animation.erb +2 -3
  87. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  88. data/lib/capybara/spec/views/with_dragula.erb +2 -2
  89. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  90. data/lib/capybara/spec/views/with_hover.erb +2 -2
  91. data/lib/capybara/spec/views/with_html.erb +1 -1
  92. data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
  93. data/lib/capybara/spec/views/with_js.erb +2 -3
  94. data/lib/capybara/spec/views/with_jstree.erb +1 -1
  95. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  96. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  97. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  98. data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
  99. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  100. data/lib/capybara/spec/views/with_windows.erb +1 -1
  101. data/lib/capybara/spec/views/within_frames.erb +1 -1
  102. data/lib/capybara/version.rb +1 -1
  103. data/lib/capybara/window.rb +1 -1
  104. data/lib/capybara.rb +19 -22
  105. data/spec/basic_node_spec.rb +16 -3
  106. data/spec/dsl_spec.rb +3 -3
  107. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
  108. data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
  109. data/spec/rack_test_spec.rb +20 -10
  110. data/spec/result_spec.rb +32 -35
  111. data/spec/rspec/features_spec.rb +3 -3
  112. data/spec/rspec/scenarios_spec.rb +1 -1
  113. data/spec/rspec/shared_spec_matchers.rb +2 -2
  114. data/spec/sauce_spec_chrome.rb +3 -3
  115. data/spec/selector_spec.rb +1 -1
  116. data/spec/selenium_spec_chrome.rb +9 -10
  117. data/spec/selenium_spec_chrome_remote.rb +9 -8
  118. data/spec/selenium_spec_firefox.rb +8 -3
  119. data/spec/selenium_spec_firefox_remote.rb +2 -2
  120. data/spec/selenium_spec_ie.rb +3 -6
  121. data/spec/selenium_spec_safari.rb +31 -19
  122. data/spec/server_spec.rb +5 -5
  123. data/spec/shared_selenium_node.rb +0 -4
  124. data/spec/shared_selenium_session.rb +20 -10
  125. data/spec/spec_helper.rb +1 -1
  126. metadata +37 -14
  127. data/lib/capybara/spec/views/with_title.erb +0 -5
@@ -15,7 +15,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
15
15
  el = @session.find(:css, '#scroll')
16
16
  @session.scroll_to(el, align: :bottom)
17
17
  el_bottom = el.evaluate_script('this.getBoundingClientRect().bottom')
18
- viewport_bottom = el.evaluate_script('document.body.clientHeight')
18
+ viewport_bottom = el.evaluate_script('document.documentElement.clientHeight')
19
19
  expect(el_bottom).to be_within(1).of(viewport_bottom)
20
20
  end
21
21
 
@@ -23,7 +23,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
23
23
  el = @session.find(:css, '#scroll')
24
24
  @session.scroll_to(el, align: :center)
25
25
  el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
26
- viewport_bottom = el.evaluate_script('document.body.clientHeight')
26
+ viewport_bottom = el.evaluate_script('document.documentElement.clientHeight')
27
27
  expect(el_center).to be_within(2).of(viewport_bottom / 2)
28
28
  end
29
29
 
@@ -35,13 +35,13 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
35
35
 
36
36
  it 'can scroll the window to the vertical bottom' do
37
37
  @session.scroll_to :bottom
38
- max_scroll = @session.evaluate_script('document.body.scrollHeight - document.body.clientHeight')
38
+ max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
39
39
  expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll]
40
40
  end
41
41
 
42
42
  it 'can scroll the window to the vertical center' do
43
43
  @session.scroll_to :center
44
- max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.body.clientHeight')
44
+ max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
45
45
  expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll / 2]
46
46
  end
47
47
 
@@ -201,4 +201,18 @@ Capybara::SpecHelper.spec '#visit' do
201
201
  @session.visit('/get_cookie')
202
202
  expect(@session).to have_content('root cookie')
203
203
  end
204
+
205
+ context 'with base element' do
206
+ it 'should use base href with relative links' do
207
+ @session.visit('/base/with_base')
208
+ @session.click_link('Title page')
209
+ expect(@session).to have_current_path('/with_title')
210
+ end
211
+
212
+ it 'should use base href with bare queries' do
213
+ @session.visit('/base/with_base')
214
+ @session.click_link('Bare query')
215
+ expect(@session).to have_current_path('/?a=3')
216
+ end
217
+ end
204
218
  end
@@ -59,7 +59,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
59
59
  it 'should return false if window is closed' do
60
60
  @session.switch_to_window(other_window)
61
61
  other_window.close
62
- expect(other_window.current?).to eq(false)
62
+ expect(other_window.current?).to be(false)
63
63
  end
64
64
  end
65
65
 
@@ -36,7 +36,7 @@ module Capybara
36
36
  Capybara.test_id = nil
37
37
  Capybara.predicates_wait = true
38
38
  Capybara.default_normalize_ws = false
39
- Capybara.allow_gumbo = true
39
+ Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil?
40
40
  Capybara.w3c_click_offset = false
41
41
  reset_threadsafe
42
42
  end
@@ -117,8 +117,9 @@ module Capybara
117
117
 
118
118
  def extract_results(session)
119
119
  expect(session).to have_xpath("//pre[@id='results']")
120
- # YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
121
- YAML.load Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
120
+ perms = [(::Sinatra::IndifferentHash if defined? ::Sinatra::IndifferentHash)].compact
121
+ results = Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
122
+ YAML.safe_load results, permitted_classes: perms
122
123
  end
123
124
 
124
125
  def be_an_invalid_element_error(session)
@@ -53,8 +53,8 @@ class TestApp < Sinatra::Base
53
53
 
54
54
  get '/referer_base' do
55
55
  '<a href="/get_referer">direct link</a>' \
56
- '<a href="/redirect_to_get_referer">link via redirect</a>' \
57
- '<form action="/get_referer" method="get"><input type="submit"></form>'
56
+ '<a href="/redirect_to_get_referer">link via redirect</a>' \
57
+ '<form action="/get_referer" method="get"><input type="submit"></form>'
58
58
  end
59
59
 
60
60
  get '/redirect_to_get_referer' do
@@ -163,21 +163,63 @@ class TestApp < Sinatra::Base
163
163
 
164
164
  get '/with_title' do
165
165
  <<-HTML
166
- <title>#{params[:title] || 'Test Title'}</title>
167
- <body>
168
- <svg><title>abcdefg</title></svg>
169
- </body>
166
+ <!DOCTYPE html>
167
+ <html lang="en">
168
+ <head>
169
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
170
+ <title>#{params[:title] || 'Test Title'}</title>
171
+ </head>
172
+
173
+ <body>
174
+ <svg><title>abcdefg</title></svg>
175
+ </body>
176
+ </html>
177
+ HTML
178
+ end
179
+
180
+ get '/base/with_base' do
181
+ <<-HTML
182
+ <!DOCTYPE html>
183
+ <html>
184
+ <head>
185
+ <base href="/">
186
+ <title>Origin</title>
187
+ </head>
188
+ <body>
189
+ <a href="with_title">Title page</a>
190
+ <a href="?a=3">Bare query</a>
191
+ </body>
192
+ </html>
193
+ HTML
194
+ end
195
+
196
+ get '/csp' do
197
+ response.headers['Content-Security-Policy'] = "default-src 'none'; connect-src 'self'; base-uri 'none'; font-src 'self'; img-src 'self' data:; object-src 'none'; script-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; style-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; form-action 'self';"
198
+ <<-HTML
199
+ <!DOCTYPE html>
200
+ <html lang="en">
201
+ <head>
202
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
203
+ <title>CSP</title>
204
+ </head>
205
+
206
+ <body>
207
+ <div>CSP</div>
208
+ </body>
209
+ </html>
170
210
  HTML
171
211
  end
172
212
 
173
213
  get '/download.csv' do
174
214
  content_type 'text/csv'
175
215
  'This, is, comma, separated' \
176
- 'Thomas, Walpole, was , here'
216
+ 'Thomas, Walpole, was , here'
177
217
  end
178
218
 
179
219
  get '/:view' do |view|
180
- erb view.to_sym, locals: { referrer: request.referrer }
220
+ view_template = "#{__dir__}/views/#{view}.erb"
221
+ has_layout = File.exist?(view_template) && File.open(view_template) { |f| f.first.downcase.include?('doctype') }
222
+ erb view.to_sym, locals: { referrer: request.referrer }, layout: !has_layout
181
223
  end
182
224
 
183
225
  post '/form' do
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -46,4 +47,3 @@
46
47
 
47
48
  <iframe id="frameOne" src="/frame_one"></iframe>
48
49
  </html>
49
-
@@ -1,11 +1,17 @@
1
-
2
1
  <h1>Form</h1>
3
2
 
3
+ <button type="button" tabindex="1">A Button</button>
4
+
5
+ <label>
6
+ An Input
7
+ <input type="text" tabindex="2">
8
+ </label>
9
+
4
10
  <form action="/form" method="post" novalidate>
5
11
 
6
12
  <p>
7
13
  <label for="form_title">Title</label>
8
- <select name="form[title]" id="form_title" class="title">
14
+ <select name="form[title]" id="form_title" class="title" tabindex="3">
9
15
  <option class="title">Mrs</option>
10
16
  <option class="title">Mr</option>
11
17
  <option>Miss</option>
@@ -170,7 +176,7 @@ New line after and before textarea tag
170
176
  <label for="gender_male">Male</label>
171
177
  <input type="radio" name="form[gender]" value="female" id="gender_female" checked="checked"/>
172
178
  <label for="gender_female">Female</label>
173
- <input type="radio" name="form[gender]" value="both" id="gender_both"/>
179
+ <input type="radio" name="form[gender]" value="both" id="gender_both" readonly="readonly"/>
174
180
  <label for="gender_both">Both</label>
175
181
  </p>
176
182
 
@@ -223,6 +229,8 @@ New line after and before textarea tag
223
229
  </label>
224
230
  <input type="checkbox" value="maserati" name="form[cars][]" id="form_cars_maserati" disabled="disabled"/>
225
231
  <label for="form_cars_maserati">Maserati</label>
232
+ <input type="checkbox" value="lotus" name="form[cars][]" id="form_cars_lotus" style="display: none"/>
233
+ <label for="form_cars_lotus"><a href="#" onclick="return false;">Link here</a>Lotus</label>
226
234
  </p>
227
235
 
228
236
  <p>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>This is the child frame title</title>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>This is the title of frame one</title>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>This is the parent frame title</title>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>This is the title of frame two</title>
@@ -1,4 +1,5 @@
1
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
2
3
  <body>
3
4
  <div>
4
5
  Initial alert page
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
+ </head>
6
+
7
+ <body>
8
+ <%= yield %>
9
+ </body>
10
+ </html>
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -44,4 +45,3 @@
44
45
  </div>
45
46
  </body>
46
47
  </html>
47
-
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -29,4 +30,4 @@
29
30
  <div id="clicker"></div>
30
31
  </div>
31
32
  </body>
32
- </html>
33
+ </html>
@@ -1,5 +1,5 @@
1
-
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
3
  <body>
4
4
  <div>
5
5
  <a href="#">First Link</a>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>Title of the first popup</title>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>Title of popup two</title>
@@ -1,4 +1,4 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <script src="https://unpkg.com/react/umd/react.development.js"></script>
@@ -42,4 +42,4 @@
42
42
  document.getElementById('root'));
43
43
  </script>
44
44
  </body>
45
- </html>
45
+ </html>
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html style="height: 250%; width: 150%">
2
3
  <head>
3
4
  <style>
@@ -17,4 +18,4 @@
17
18
  </div>
18
19
  </div>
19
20
  </body>
20
- </html>
21
+ </html>
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -28,4 +29,3 @@
28
29
  <div class="footer distance">10</div>
29
30
  </body>
30
31
  </html>
31
-
@@ -1,5 +1,5 @@
1
-
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
5
  <title>with_animation</title>
@@ -79,4 +79,3 @@
79
79
  </a>
80
80
  </body>
81
81
  </html>
82
-
@@ -1,5 +1,5 @@
1
-
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
5
  <base href="http://example2.com" />
@@ -1,4 +1,5 @@
1
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
5
  <title>with_dragula</title>
@@ -21,4 +22,3 @@
21
22
  </script>
22
23
  </body>
23
24
  </html>
24
-
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <style>
@@ -14,4 +15,4 @@
14
15
  <a href="/">Go to root</a>
15
16
  </div>
16
17
  <footer>My footer</footer>
17
- </body>
18
+ </body>
@@ -1,5 +1,5 @@
1
-
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
5
  <title>with_hover</title>
@@ -19,7 +19,7 @@
19
19
 
20
20
  <p class="para" id="first" data-random="abc\def" style="line-height: 25px;">
21
21
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
22
- tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
22
+ tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1">labore</a>
23
23
  et dolore magna aliqua. Ut enim ad minim veniam,
24
24
  quis nostrud exercitation <a href="/foo" id="foo" data-test-id="test-foo">ullamco</a> laboris nisi
25
25
  ut aliquip ex ea commodo consequat.
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -1,5 +1,5 @@
1
-
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
5
  <title>with_js</title>
@@ -160,4 +160,3 @@
160
160
  </script>
161
161
  </body>
162
162
  </html>
163
-
@@ -1,4 +1,4 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1
2
  <html xmlns="http://www.w3.org/1999/xhtml">
2
3
  <head>
3
4
  <title>Namespace</title>
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <%# Borrowed from Titus Fortner %>
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6
+ <title>Shadow DOM</title>
7
+ </head>
8
+ <body>
9
+ <div id="no_host"></div>
10
+ <div id="shadow_host"></div>
11
+ <a href="scroll.html">scroll.html</a>
12
+ <script>
13
+ let shadowRoot = document.getElementById('shadow_host').attachShadow({mode: 'open'});
14
+ shadowRoot.innerHTML = `
15
+ <span class="wrapper" id="shadow_content"><span class="info">some text</span></span>
16
+ <div id="nested_shadow_host"></div>
17
+ <a href="scroll.html">scroll.html</a>
18
+ <div id="controls_wrapper">
19
+ <input type="text" />
20
+ <input type="checkbox" id="shadow_checkbox" />
21
+ <input type="file" />
22
+ </div>
23
+ `;
24
+
25
+ let nestedShadowRoot = shadowRoot.getElementById('nested_shadow_host').attachShadow({mode: 'open'});
26
+ nestedShadowRoot.innerHTML = `
27
+ <div id="nested_shadow_content"><div>nested text</div></div>
28
+ `;
29
+ </script>
30
+ </body>
31
+ </html>
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <script>
@@ -14,4 +15,4 @@
14
15
  <body>
15
16
  <div>This delays unload by 2 seconds</div>
16
17
  </body>
17
- </html>
18
+ </html>
@@ -1,4 +1,5 @@
1
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
1
+ <!DOCTYPE html>
2
+ <html lang="en">
2
3
  <head>
3
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
5
  <title>with_sortable_js</title>
@@ -18,4 +19,3 @@
18
19
  </script>
19
20
  </body>
20
21
  </html>
21
-
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <script>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>With Windows</title>
@@ -1,4 +1,4 @@
1
-
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>With Frames</title>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.35.2'
4
+ VERSION = '3.37.0'
5
5
  end
@@ -118,7 +118,7 @@ module Capybara
118
118
  alias_method :==, :eql?
119
119
 
120
120
  def hash
121
- @session.hash ^ @handle.hash
121
+ [@session, @handle].hash
122
122
  end
123
123
 
124
124
  def inspect
data/lib/capybara.rb CHANGED
@@ -39,7 +39,7 @@ module Capybara
39
39
  # See {Capybara.configure}
40
40
  # @!method javascript_driver
41
41
  # See {Capybara.configure}
42
- # @!method allow_gumbo
42
+ # @!method use_html5_parsing
43
43
  # See {Capybara.configure}
44
44
  Config::OPTIONS.each do |method|
45
45
  def_delegators :config, method, "#{method}="
@@ -69,7 +69,7 @@ module Capybara
69
69
  #
70
70
  # #### Configurable options
71
71
  #
72
- # - **allow_gumbo** (Boolean = `false`) - When `nokogumbo` is available, whether it will be used to parse HTML strings.
72
+ # - **use_html5_parsing** (Boolean = `false`) - When Nokogiri >= 1.12.0 or `nokogumbo` is installed, whether HTML5 parsing will be used for HTML strings.
73
73
  # - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
74
74
  # unless another port is explicitly specified.
75
75
  # - **app_host** (String, `nil`) - The default host to use when giving a relative URL to visit, must be a valid URL e.g. `http://www.example.com`.
@@ -96,6 +96,7 @@ module Capybara
96
96
  # {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
97
97
  # - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
98
98
  # - **server_port** (Integer) - The port Capybara will run the application server on, if not specified a random port will be used.
99
+ # - **server_host** (String = "127.0.0.1") - The IP address Capybara will bind the application server to. If the test application is to be accessed from an external host, you will want to change this to "0.0.0.0" or to a more specific IP address that your test client can reach.
99
100
  # - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
100
101
  # and {configure raise_server_errors} is `true`.
101
102
  # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
@@ -385,26 +386,21 @@ module Capybara
385
386
  # @return [Nokogiri::HTML::Document] HTML document
386
387
  #
387
388
  def HTML(html) # rubocop:disable Naming/MethodName
388
- if Nokogiri.respond_to?(:HTML5) && Capybara.allow_gumbo # Nokogumbo installed and allowed for use
389
- Nokogiri::HTML5(html).tap do |document|
390
- document.xpath('//template').each do |template|
391
- # template elements content is not part of the document
392
- template.inner_html = ''
393
- end
394
- document.xpath('//textarea').each do |textarea|
395
- # The Nokogumbo HTML5 parser already returns spec compliant contents
396
- textarea['_capybara_raw_value'] = textarea.content
397
- end
398
- end
389
+ # Nokogiri >= 1.12.0 or Nokogumbo installed and allowed for use
390
+ html_parser, using_html5 = if defined?(Nokogiri::HTML5) && Capybara.use_html5_parsing
391
+ [Nokogiri::HTML5, true]
399
392
  else
400
- Nokogiri::HTML(html).tap do |document|
401
- document.xpath('//template').each do |template|
402
- # template elements content is not part of the document
403
- template.inner_html = ''
404
- end
405
- document.xpath('//textarea').each do |textarea|
406
- textarea['_capybara_raw_value'] = textarea.content.delete_prefix("\n")
407
- end
393
+ [defined?(Nokogiri::HTML4) ? Nokogiri::HTML4 : Nokogiri::HTML, false]
394
+ end
395
+
396
+ html_parser.parse(html).tap do |document|
397
+ document.xpath('//template').each do |template|
398
+ # template elements content is not part of the document
399
+ template.inner_html = ''
400
+ end
401
+ document.xpath('//textarea').each do |textarea|
402
+ # The Nokogiri HTML5 parser already returns spec compliant contents
403
+ textarea['_capybara_raw_value'] = using_html5 ? textarea.content : textarea.content.delete_prefix("\n")
408
404
  end
409
405
  end
410
406
  end
@@ -467,6 +463,7 @@ module Capybara
467
463
  require 'capybara/queries/ancestor_query'
468
464
  require 'capybara/queries/sibling_query'
469
465
  require 'capybara/queries/style_query'
466
+ require 'capybara/queries/active_element_query'
470
467
 
471
468
  require 'capybara/node/finders'
472
469
  require 'capybara/node/matchers'
@@ -516,6 +513,6 @@ Capybara.configure do |config|
516
513
  config.test_id = nil
517
514
  config.predicates_wait = true
518
515
  config.default_normalize_ws = false
519
- config.allow_gumbo = false
516
+ config.use_html5_parsing = false
520
517
  config.w3c_click_offset = false
521
518
  end