capybara 3.29.0 → 3.31.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +40 -1
  3. data/README.md +1 -1
  4. data/lib/capybara/config.rb +7 -3
  5. data/lib/capybara/dsl.rb +10 -2
  6. data/lib/capybara/helpers.rb +3 -1
  7. data/lib/capybara/minitest.rb +18 -4
  8. data/lib/capybara/node/actions.rb +23 -19
  9. data/lib/capybara/node/document.rb +2 -2
  10. data/lib/capybara/node/document_matchers.rb +3 -3
  11. data/lib/capybara/node/element.rb +21 -16
  12. data/lib/capybara/node/finders.rb +17 -11
  13. data/lib/capybara/node/matchers.rb +60 -45
  14. data/lib/capybara/node/simple.rb +4 -2
  15. data/lib/capybara/queries/ancestor_query.rb +1 -1
  16. data/lib/capybara/queries/base_query.rb +2 -1
  17. data/lib/capybara/queries/selector_query.rb +17 -4
  18. data/lib/capybara/queries/sibling_query.rb +1 -1
  19. data/lib/capybara/rack_test/browser.rb +4 -1
  20. data/lib/capybara/rack_test/driver.rb +1 -1
  21. data/lib/capybara/rack_test/form.rb +1 -1
  22. data/lib/capybara/rack_test/node.rb +34 -9
  23. data/lib/capybara/result.rb +24 -4
  24. data/lib/capybara/rspec/matchers.rb +27 -27
  25. data/lib/capybara/rspec/matchers/base.rb +12 -6
  26. data/lib/capybara/rspec/matchers/count_sugar.rb +2 -1
  27. data/lib/capybara/rspec/matchers/have_ancestor.rb +4 -3
  28. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  29. data/lib/capybara/rspec/matchers/have_selector.rb +15 -7
  30. data/lib/capybara/rspec/matchers/have_sibling.rb +3 -3
  31. data/lib/capybara/rspec/matchers/have_text.rb +2 -2
  32. data/lib/capybara/rspec/matchers/have_title.rb +2 -2
  33. data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
  34. data/lib/capybara/rspec/matchers/match_style.rb +2 -2
  35. data/lib/capybara/rspec/matchers/spatial_sugar.rb +2 -1
  36. data/lib/capybara/selector.rb +24 -16
  37. data/lib/capybara/selector/css.rb +1 -1
  38. data/lib/capybara/selector/definition.rb +2 -2
  39. data/lib/capybara/selector/definition/button.rb +7 -2
  40. data/lib/capybara/selector/definition/checkbox.rb +2 -2
  41. data/lib/capybara/selector/definition/css.rb +3 -1
  42. data/lib/capybara/selector/definition/datalist_input.rb +1 -1
  43. data/lib/capybara/selector/definition/datalist_option.rb +1 -1
  44. data/lib/capybara/selector/definition/element.rb +1 -1
  45. data/lib/capybara/selector/definition/field.rb +1 -1
  46. data/lib/capybara/selector/definition/file_field.rb +1 -1
  47. data/lib/capybara/selector/definition/fillable_field.rb +1 -1
  48. data/lib/capybara/selector/definition/label.rb +4 -2
  49. data/lib/capybara/selector/definition/radio_button.rb +2 -2
  50. data/lib/capybara/selector/definition/select.rb +32 -13
  51. data/lib/capybara/selector/definition/table.rb +5 -2
  52. data/lib/capybara/selector/filter_set.rb +11 -9
  53. data/lib/capybara/selector/filters/base.rb +6 -1
  54. data/lib/capybara/selector/filters/locator_filter.rb +1 -1
  55. data/lib/capybara/selector/selector.rb +4 -2
  56. data/lib/capybara/selenium/driver.rb +19 -11
  57. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
  58. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -2
  59. data/lib/capybara/selenium/extensions/html5_drag.rb +30 -13
  60. data/lib/capybara/selenium/node.rb +29 -10
  61. data/lib/capybara/selenium/nodes/chrome_node.rb +11 -5
  62. data/lib/capybara/selenium/nodes/edge_node.rb +4 -2
  63. data/lib/capybara/selenium/nodes/firefox_node.rb +2 -2
  64. data/lib/capybara/server.rb +15 -3
  65. data/lib/capybara/server/checker.rb +1 -1
  66. data/lib/capybara/server/middleware.rb +20 -10
  67. data/lib/capybara/session.rb +40 -23
  68. data/lib/capybara/session/config.rb +6 -2
  69. data/lib/capybara/session/matchers.rb +6 -6
  70. data/lib/capybara/spec/public/test.js +51 -6
  71. data/lib/capybara/spec/session/all_spec.rb +60 -5
  72. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  73. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  74. data/lib/capybara/spec/session/click_button_spec.rb +5 -0
  75. data/lib/capybara/spec/session/fill_in_spec.rb +20 -0
  76. data/lib/capybara/spec/session/find_spec.rb +20 -0
  77. data/lib/capybara/spec/session/has_css_spec.rb +3 -3
  78. data/lib/capybara/spec/session/has_select_spec.rb +28 -0
  79. data/lib/capybara/spec/session/has_table_spec.rb +51 -5
  80. data/lib/capybara/spec/session/has_text_spec.rb +35 -0
  81. data/lib/capybara/spec/session/node_spec.rb +106 -2
  82. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  83. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  84. data/lib/capybara/spec/session/selectors_spec.rb +15 -2
  85. data/lib/capybara/spec/views/form.erb +11 -1
  86. data/lib/capybara/version.rb +1 -1
  87. data/spec/dsl_spec.rb +2 -2
  88. data/spec/minitest_spec_spec.rb +46 -46
  89. data/spec/rack_test_spec.rb +0 -1
  90. data/spec/regexp_dissassembler_spec.rb +45 -37
  91. data/spec/result_spec.rb +7 -3
  92. data/spec/rspec/features_spec.rb +1 -0
  93. data/spec/rspec/shared_spec_matchers.rb +3 -3
  94. data/spec/rspec_spec.rb +4 -4
  95. data/spec/selenium_spec_chrome.rb +5 -4
  96. data/spec/selenium_spec_firefox.rb +7 -2
  97. data/spec/server_spec.rb +42 -0
  98. data/spec/session_spec.rb +1 -1
  99. data/spec/shared_selenium_node.rb +3 -3
  100. data/spec/shared_selenium_session.rb +8 -7
  101. metadata +3 -3
@@ -185,10 +185,10 @@ Capybara::SpecHelper.spec '#has_css?' do
185
185
  end
186
186
 
187
187
  it 'should be false when content occurs more times than given' do
188
- expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
189
- expect(@session).not_to have_css('h2', maximum: 3)
188
+ # expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
189
+ # expect(@session).not_to have_css('h2', maximum: 3)
190
190
  expect(@session).not_to have_css('h2').at_most(3).times
191
- expect(@session).not_to have_css('p', maximum: 1)
191
+ # expect(@session).not_to have_css('p', maximum: 1)
192
192
  end
193
193
 
194
194
  it 'should coerce maximum to an integer' do
@@ -117,6 +117,34 @@ Capybara::SpecHelper.spec '#has_select?' do
117
117
  end
118
118
  end
119
119
 
120
+ context 'with enabled options' do
121
+ it 'should be true if the listed options exist and are enabled' do
122
+ expect(@session).to have_select('form_title', enabled_options: %w[Mr Mrs Miss])
123
+ end
124
+
125
+ it 'should be false if the listed options do not exist' do
126
+ expect(@session).not_to have_select('form_title', enabled_options: ['Not there'])
127
+ end
128
+
129
+ it 'should be false if the listed option exists but is not enabled' do
130
+ expect(@session).not_to have_select('form_title', enabled_options: %w[Mr Mrs Miss Other])
131
+ end
132
+ end
133
+
134
+ context 'with disabled options' do
135
+ it 'should be true if the listed options exist and are disabled' do
136
+ expect(@session).to have_select('form_title', disabled_options: ['Other'])
137
+ end
138
+
139
+ it 'should be false if the listed options do not exist' do
140
+ expect(@session).not_to have_select('form_title', disabled_options: ['Not there'])
141
+ end
142
+
143
+ it 'should be false if the listed option exists but is not disabled' do
144
+ expect(@session).not_to have_select('form_title', disabled_options: %w[Other Mrs])
145
+ end
146
+ end
147
+
120
148
  context 'with partial options' do
121
149
  it 'should be true if a field with the given partial options is on the page' do
122
150
  expect(@session).to have_select('Region', with_options: %w[Norway Sweden])
@@ -143,10 +143,56 @@ Capybara::SpecHelper.spec '#has_no_table?' do
143
143
  ])
144
144
  end
145
145
 
146
- it 'should consider columns' do
147
- expect(@session).to have_no_table('Vertical Headers', with_cols:
148
- [
149
- { 'First Name' => 'Joe' }
150
- ])
146
+ context 'using :with_cols' do
147
+ it 'should consider a single column' do
148
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
149
+ [
150
+ { 'First Name' => 'Joe' }
151
+ ])
152
+ end
153
+
154
+ it 'should be true even if the last column does exist' do
155
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
156
+ [
157
+ {
158
+ 'First Name' => 'What?',
159
+ 'What?' => 'Walpole',
160
+ 'City' => 'Oceanside' # This line makes the example fail
161
+ }
162
+ ])
163
+ end
164
+
165
+ it 'should be true if none of the columns exist' do
166
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
167
+ [
168
+ {
169
+ 'First Name' => 'What?',
170
+ 'What?' => 'Walpole',
171
+ 'City' => 'What?'
172
+ }
173
+ ])
174
+ end
175
+
176
+ it 'should be true if the first column does match' do
177
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
178
+ [
179
+ {
180
+ 'First Name' => 'Thomas',
181
+ 'Last Name' => 'What',
182
+ 'City' => 'What'
183
+ }
184
+ ])
185
+ end
186
+
187
+ it 'should be true if none of the columns match' do
188
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
189
+ [
190
+ {
191
+ 'First Name' => 'What',
192
+ 'Last Name' => 'What',
193
+ 'City' => 'What'
194
+ }
195
+ ])
196
+ end
151
197
  end
152
198
  end
@@ -111,6 +111,41 @@ Capybara::SpecHelper.spec '#has_text?' do
111
111
  expect(@session).not_to have_text(/xxxxyzzz/)
112
112
  end
113
113
 
114
+ context 'with object implementing to_s and to_hash' do
115
+ it 'should work if the object is passed alone' do
116
+ with_to_hash = Class.new do
117
+ def to_s; '42' end
118
+ def to_hash; { value: 'Other hash' } end
119
+ end.new
120
+ @session.visit('/with_html')
121
+ expect(@session).to have_text(with_to_hash)
122
+ end
123
+
124
+ it 'should work if passed with empty options' do
125
+ with_to_hash = Class.new do
126
+ def to_s; '42' end
127
+ def to_hash; { value: 'Other hash' } end
128
+ end.new
129
+ @session.visit('/with_html')
130
+ if RUBY_VERSION >= '2.7'
131
+ expect(@session).to have_text(:visible, with_to_hash, **{})
132
+ else
133
+ expect(@session).to have_text(:visible, with_to_hash, {})
134
+ end
135
+ end
136
+
137
+ it 'should fail if passed without empty options' do
138
+ with_to_hash = Class.new do
139
+ def to_s; '42' end
140
+ def to_hash; { blah: 'Other hash' } end
141
+ end.new
142
+ @session.visit('/with_html')
143
+ expect do
144
+ expect(@session).to have_text(:visible, with_to_hash)
145
+ end.to raise_error(ArgumentError)
146
+ end
147
+ end
148
+
114
149
  context 'with exact: true option' do
115
150
  it 'should be true if text matches exactly' do
116
151
  @session.visit('/with_html')
@@ -270,11 +270,11 @@ Capybara::SpecHelper.spec 'node' do
270
270
  end
271
271
 
272
272
  it 'works when details is toggled open and closed' do
273
- @session.find(:css, '#closed_details').click
273
+ @session.find(:css, '#closed_details > summary').click
274
274
  expect(@session).to have_css('#closed_details *', visible: true, count: 5)
275
275
  .and(have_no_css('#closed_details *', visible: :hidden))
276
276
 
277
- @session.find(:css, '#closed_details').click
277
+ @session.find(:css, '#closed_details > summary').click
278
278
  descendants_css = '#closed_details > *:not(summary), #closed_details > *:not(summary) *'
279
279
  expect(@session).to have_no_css(descendants_css, visible: true)
280
280
  .and(have_css(descendants_css, visible: :hidden, count: 3))
@@ -468,6 +468,50 @@ Capybara::SpecHelper.spec 'node' do
468
468
  end
469
469
  end
470
470
 
471
+ it 'should simulate a single held down modifier key' do
472
+ %I[
473
+ alt
474
+ ctrl
475
+ meta
476
+ shift
477
+ ].each do |modifier_key|
478
+ @session.visit('/with_js')
479
+
480
+ element = @session.find('//div[@id="drag"]')
481
+ target = @session.find('//div[@id="drop"]')
482
+
483
+ element.drag_to(target, drop_modifiers: modifier_key)
484
+ expect(@session).to have_css('div.drag_start', exact_text: 'Dragged!')
485
+ expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_key}')]")
486
+ end
487
+ end
488
+
489
+ it 'should simulate multiple held down modifier keys' do
490
+ @session.visit('/with_js')
491
+
492
+ element = @session.find('//div[@id="drag"]')
493
+ target = @session.find('//div[@id="drop"]')
494
+
495
+ modifier_keys = %I[alt ctrl meta shift]
496
+
497
+ element.drag_to(target, drop_modifiers: modifier_keys)
498
+ expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_keys.join('-')}')]")
499
+ end
500
+
501
+ it 'should support key aliases' do
502
+ { control: :ctrl,
503
+ command: :meta,
504
+ cmd: :meta }.each do |(key_alias, key)|
505
+ @session.visit('/with_js')
506
+
507
+ element = @session.find('//div[@id="drag"]')
508
+ target = @session.find('//div[@id="drop"]')
509
+
510
+ element.drag_to(target, drop_modifiers: [key_alias])
511
+ expect(target).to have_text("Dropped!-#{key}", exact: true)
512
+ end
513
+ end
514
+
471
515
  context 'HTML5', requires: %i[js html5_drag] do
472
516
  it 'should HTML5 drag and drop an object' do
473
517
  @session.visit('/with_js')
@@ -493,6 +537,26 @@ Capybara::SpecHelper.spec 'node' do
493
537
  expect(@session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
494
538
  end
495
539
 
540
+ it 'should preserve clientX/Y from last dragover event' do
541
+ @session.visit('/with_js')
542
+ element = @session.find('//div[@id="drag_html5"]')
543
+ target = @session.find('//div[@id="drop_html5"]')
544
+ element.drag_to(target)
545
+
546
+ conditions = %w[DragLeave Drop DragEnd].map do |text|
547
+ have_css('div.log', text: text)
548
+ end
549
+ expect(@session).to(conditions.reduce { |memo, cond| memo.and(cond) })
550
+
551
+ # The first "DragOver" div is inserted by the last dragover event dispatched
552
+ drag_over_div = @session.first('//div[@class="log" and starts-with(text(), "DragOver")]')
553
+ position = drag_over_div.text.sub('DragOver ', '')
554
+
555
+ expect(@session).to have_css('div.log', text: /DragLeave #{position}/, count: 1)
556
+ expect(@session).to have_css('div.log', text: /Drop #{position}/, count: 1)
557
+ expect(@session).to have_css('div.log', text: /DragEnd #{position}/, count: 1)
558
+ end
559
+
496
560
  it 'should not HTML5 drag and drop on a non HTML5 drop element' do
497
561
  @session.visit('/with_js')
498
562
  element = @session.find('//div[@id="drag_html5"]')
@@ -536,6 +600,46 @@ Capybara::SpecHelper.spec 'node' do
536
600
  source.drag_to target
537
601
  expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
538
602
  end
603
+
604
+ it 'should simulate a single held down modifier key' do
605
+ %I[alt ctrl meta shift].each do |modifier_key|
606
+ @session.visit('/with_js')
607
+
608
+ element = @session.find('//div[@id="drag_html5"]')
609
+ target = @session.find('//div[@id="drop_html5"]')
610
+
611
+ element.drag_to(target, drop_modifiers: modifier_key)
612
+
613
+ expect(@session).to have_css('div.drag_start', exact_text: 'HTML5 Dragged!')
614
+ expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_key}')]")
615
+ end
616
+ end
617
+
618
+ it 'should simulate multiple held down modifier keys' do
619
+ @session.visit('/with_js')
620
+
621
+ element = @session.find('//div[@id="drag_html5"]')
622
+ target = @session.find('//div[@id="drop_html5"]')
623
+
624
+ modifier_keys = %I[alt ctrl meta shift]
625
+
626
+ element.drag_to(target, drop_modifiers: modifier_keys)
627
+ expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_keys.join('-')}')]")
628
+ end
629
+
630
+ it 'should support key aliases' do
631
+ { control: :ctrl,
632
+ command: :meta,
633
+ cmd: :meta }.each do |(key_alias, key)|
634
+ @session.visit('/with_js')
635
+
636
+ element = @session.find('//div[@id="drag_html5"]')
637
+ target = @session.find('//div[@id="drop_html5"]')
638
+
639
+ element.drag_to(target, drop_modifiers: [key_alias])
640
+ expect(target).to have_text(%r{^HTML5 Dropped string: text/plain drag_html5-#{key}$}m, exact: true)
641
+ end
642
+ end
539
643
  end
540
644
  end
541
645
 
@@ -15,7 +15,7 @@ Capybara::SpecHelper.spec '#save_and_open_screenshot' do
15
15
  @session.save_and_open_screenshot
16
16
 
17
17
  expect(@session.driver).to have_received(:save_screenshot)
18
- .with(expected_file_regex, {})
18
+ .with(expected_file_regex, any_args)
19
19
  expect(Launchy).to have_received(:open).with(expected_file_regex)
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ Capybara::SpecHelper.spec '#save_and_open_screenshot' do
27
27
  @session.save_and_open_screenshot(custom_path)
28
28
 
29
29
  expect(@session.driver).to have_received(:save_screenshot)
30
- .with(/#{custom_path}$/, {})
30
+ .with(/#{custom_path}$/, any_args)
31
31
  expect(Launchy).to have_received(:open).with(/#{custom_path}$/)
32
32
  end
33
33
 
@@ -19,7 +19,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
19
19
  @session.save_screenshot
20
20
 
21
21
  regexp = Regexp.new(File.join(Dir.pwd, 'capybara-\d+\.png'))
22
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
22
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
23
23
  end
24
24
 
25
25
  it 'allows to specify another path' do
@@ -28,7 +28,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
28
28
  custom_path = 'screenshots/1.png'
29
29
  @session.save_screenshot(custom_path)
30
30
 
31
- expect(@session.driver).to have_received(:save_screenshot).with(/#{custom_path}$/, {})
31
+ expect(@session.driver).to have_received(:save_screenshot).with(/#{custom_path}$/, any_args)
32
32
  end
33
33
 
34
34
  context 'with Capybara.save_path' do
@@ -39,7 +39,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
39
39
  @session.save_screenshot
40
40
 
41
41
  regexp = Regexp.new(File.join(alternative_path, 'capybara-\d+\.png'))
42
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
42
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
43
43
  end
44
44
 
45
45
  it 'relative paths are relative to save_path' do
@@ -49,7 +49,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
49
49
  custom_path = 'screenshots/2.png'
50
50
  @session.save_screenshot(custom_path)
51
51
 
52
- expect(@session.driver).to have_received(:save_screenshot).with(File.expand_path(custom_path, alternative_path), {})
52
+ expect(@session.driver).to have_received(:save_screenshot).with(File.expand_path(custom_path, alternative_path), any_args)
53
53
  end
54
54
  end
55
55
  end
@@ -31,6 +31,11 @@ Capybara::SpecHelper.spec Capybara::Selector do
31
31
  expect(@session.find(:label, for: input).text).to eq 'Nested Label'
32
32
  end
33
33
 
34
+ it 'finds a label from nested input using :for filter with element when no id on label' do
35
+ input = @session.find(:css, '#wrapper_label').find(:css, 'input')
36
+ expect(@session.find(:label, for: input).text).to eq 'Wrapper Label'
37
+ end
38
+
34
39
  it 'finds the label for an non-nested element when using :for filter' do
35
40
  select = @session.find(:id, 'form_other_title')
36
41
  expect(@session.find(:label, for: select)['for']).to eq 'form_other_title'
@@ -62,14 +67,22 @@ Capybara::SpecHelper.spec Capybara::Selector do
62
67
  end
63
68
  end
64
69
 
65
- it 'can find specifically by name' do
70
+ it 'can find specifically by name string' do
66
71
  expect(@session.find(:field, name: 'form[other_title]')['id']).to eq 'form_other_title'
67
72
  end
68
73
 
69
- it 'can find specifically by placeholder' do
74
+ it 'can find specifically by name regex' do
75
+ expect(@session.find(:field, name: /form\[other_.*\]/)['id']).to eq 'form_other_title'
76
+ end
77
+
78
+ it 'can find specifically by placeholder string' do
70
79
  expect(@session.find(:field, placeholder: 'FirstName')['id']).to eq 'form_first_name'
71
80
  end
72
81
 
82
+ it 'can find specifically by placeholder regex' do
83
+ expect(@session.find(:field, placeholder: /FirstN.*/)['id']).to eq 'form_first_name'
84
+ end
85
+
73
86
  it 'can find by type' do
74
87
  expect(@session.find(:field, 'Confusion', type: 'checkbox')['id']).to eq 'confusion_checkbox'
75
88
  expect(@session.find(:field, 'Confusion', type: 'text')['id']).to eq 'confusion_text'
@@ -11,7 +11,7 @@
11
11
  <option>Miss</option>
12
12
  <option disabled="disabled">Other</option>
13
13
  </select>
14
- </p>
14
+ </p>
15
15
 
16
16
  <p>
17
17
  <label for="customer_name">Customer Name
@@ -62,6 +62,11 @@
62
62
  <input type="text" name="form[name]" value="John Smith" id="form_name"/>
63
63
  </p>
64
64
 
65
+ <p>
66
+ <label for="form_age">Age</label>
67
+ <input type="range" name="form[age]" value="18" min="13" max="100" step="0.5" id="form_age"/>
68
+ </p>
69
+
65
70
  <p>
66
71
  <label for="form_schmooo">Schmooo</label>
67
72
  <input type="schmooo" name="form[schmooo]" value="This is Schmooo!" id="form_schmooo"/>
@@ -474,6 +479,11 @@ New line after and before textarea tag
474
479
  <input type="text" name="nested_label" id="nested_label"/>
475
480
  </label>
476
481
 
482
+ <label id="wrapper_label">
483
+ Wrapper Label
484
+ <input type="checkbox"/>
485
+ </label>
486
+
477
487
  <form id="form1" action="/form" method="post">
478
488
  <input type="text" name="form[which_form]" value="form1" id="form_which_form"/>
479
489
  <input type="text" name="form[for_form2]" value="for_form2" form="form2"/>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.29.0'
4
+ VERSION = '3.31.0'
5
5
  end
@@ -92,7 +92,7 @@ RSpec.describe Capybara::DSL do
92
92
  driver_before_block = Capybara.current_driver
93
93
  begin
94
94
  Capybara.using_driver(:selenium) { raise 'ohnoes!' }
95
- rescue Exception # rubocop:disable Lint/RescueException,Lint/HandleExceptions
95
+ rescue Exception # rubocop:disable Lint/RescueException,Lint/SuppressedException
96
96
  end
97
97
  expect(Capybara.current_driver).to eq(driver_before_block)
98
98
  end
@@ -208,7 +208,7 @@ RSpec.describe Capybara::DSL do
208
208
  Capybara.using_session(:raise) do
209
209
  raise
210
210
  end
211
- rescue Exception # rubocop:disable Lint/RescueException,Lint/HandleExceptions
211
+ rescue Exception # rubocop:disable Lint/RescueException,Lint/SuppressedException
212
212
  end
213
213
  expect(Capybara.session_name).to eq(:default)
214
214
  end
@@ -17,125 +17,125 @@ class MinitestSpecTest < Minitest::Spec
17
17
  end
18
18
 
19
19
  it 'supports text expectations' do
20
- page.must_have_text('Form', minimum: 1)
21
- page.wont_have_text('Not a form')
20
+ _(page).must_have_text('Form', minimum: 1)
21
+ _(page).wont_have_text('Not a form')
22
22
  form = find(:css, 'form', text: 'Title')
23
- form.must_have_text('Customer Email')
24
- form.wont_have_text('Some other email')
23
+ _(form).must_have_text('Customer Email')
24
+ _(form).wont_have_text('Some other email')
25
25
  end
26
26
 
27
27
  it 'supports current_path expectations' do
28
- page.must_have_current_path('/form')
29
- page.wont_have_current_path('/form2')
28
+ _(page).must_have_current_path('/form')
29
+ _(page).wont_have_current_path('/form2')
30
30
  end
31
31
 
32
32
  it 'supports title expectations' do
33
33
  visit('/with_title')
34
- page.must_have_title('Test Title')
35
- page.wont_have_title('Not the title')
34
+ _(page).must_have_title('Test Title')
35
+ _(page).wont_have_title('Not the title')
36
36
  end
37
37
 
38
38
  it 'supports xpath expectations' do
39
- page.must_have_xpath('.//input[@id="customer_email"]')
40
- page.wont_have_xpath('.//select[@id="not_form_title"]')
41
- page.wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == 'not_customer_email' }
39
+ _(page).must_have_xpath('.//input[@id="customer_email"]')
40
+ _(page).wont_have_xpath('.//select[@id="not_form_title"]')
41
+ _(page).wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == 'not_customer_email' }
42
42
  select = find(:select, 'form_title')
43
- select.must_have_xpath('.//option[@class="title"]')
44
- select.must_have_xpath('.//option', count: 1) { |option| option[:class] != 'title' && !option.disabled? }
45
- select.wont_have_xpath('.//input[@id="customer_email"]')
43
+ _(select).must_have_xpath('.//option[@class="title"]')
44
+ _(select).must_have_xpath('.//option', count: 1) { |option| option[:class] != 'title' && !option.disabled? }
45
+ _(select).wont_have_xpath('.//input[@id="customer_email"]')
46
46
  end
47
47
 
48
48
  it 'support css expectations' do
49
- page.must_have_css('input#customer_email')
50
- page.wont_have_css('select#not_form_title')
49
+ _(page).must_have_css('input#customer_email')
50
+ _(page).wont_have_css('select#not_form_title')
51
51
  el = find(:select, 'form_title')
52
- el.must_have_css('option.title')
53
- el.wont_have_css('input#customer_email')
52
+ _(el).must_have_css('option.title')
53
+ _(el).wont_have_css('input#customer_email')
54
54
  end
55
55
 
56
56
  it 'supports link expectations' do
57
57
  visit('/with_html')
58
- page.must_have_link('A link')
59
- page.wont_have_link('Not on page')
58
+ _(page).must_have_link('A link')
59
+ _(page).wont_have_link('Not on page')
60
60
  end
61
61
 
62
62
  it 'supports button expectations' do
63
- page.must_have_button('fresh_btn')
64
- page.wont_have_button('not_btn')
63
+ _(page).must_have_button('fresh_btn')
64
+ _(page).wont_have_button('not_btn')
65
65
  end
66
66
 
67
67
  it 'supports field expectations' do
68
- page.must_have_field('customer_email')
69
- page.wont_have_field('not_on_the_form')
68
+ _(page).must_have_field('customer_email')
69
+ _(page).wont_have_field('not_on_the_form')
70
70
  end
71
71
 
72
72
  it 'supports select expectations' do
73
- page.must_have_select('form_title')
74
- page.wont_have_select('not_form_title')
73
+ _(page).must_have_select('form_title')
74
+ _(page).wont_have_select('not_form_title')
75
75
  end
76
76
 
77
77
  it 'supports checked_field expectations' do
78
- page.must_have_checked_field('form_pets_dog')
79
- page.wont_have_checked_field('form_pets_cat')
78
+ _(page).must_have_checked_field('form_pets_dog')
79
+ _(page).wont_have_checked_field('form_pets_cat')
80
80
  end
81
81
 
82
82
  it 'supports unchecked_field expectations' do
83
- page.must_have_unchecked_field('form_pets_cat')
84
- page.wont_have_unchecked_field('form_pets_dog')
83
+ _(page).must_have_unchecked_field('form_pets_cat')
84
+ _(page).wont_have_unchecked_field('form_pets_dog')
85
85
  end
86
86
 
87
87
  it 'supports table expectations' do
88
88
  visit('/tables')
89
- page.must_have_table('agent_table')
90
- page.wont_have_table('not_on_form')
89
+ _(page).must_have_table('agent_table')
90
+ _(page).wont_have_table('not_on_form')
91
91
  end
92
92
 
93
93
  it 'supports all_of_selectors expectations' do
94
- page.must_have_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
94
+ _(page).must_have_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
95
95
  end
96
96
 
97
97
  it 'supports none_of_selectors expectations' do
98
- page.must_have_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
98
+ _(page).must_have_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
99
99
  end
100
100
 
101
101
  it 'supports any_of_selectors expectations' do
102
- page.must_have_any_of_selectors(:css, 'select#form_other_title', 'input#not_on_page')
102
+ _(page).must_have_any_of_selectors(:css, 'select#form_other_title', 'input#not_on_page')
103
103
  end
104
104
 
105
105
  it 'supports match_selector expectations' do
106
- find(:field, 'customer_email').must_match_selector(:field, 'customer_email')
107
- find(:select, 'form_title').wont_match_selector(:field, 'customer_email')
106
+ _(find(:field, 'customer_email')).must_match_selector(:field, 'customer_email')
107
+ _(find(:select, 'form_title')).wont_match_selector(:field, 'customer_email')
108
108
  end
109
109
 
110
110
  it 'supports match_css expectations' do
111
- find(:select, 'form_title').must_match_css('select#form_title')
112
- find(:select, 'form_title').wont_match_css('select#form_other_title')
111
+ _(find(:select, 'form_title')).must_match_css('select#form_title')
112
+ _(find(:select, 'form_title')).wont_match_css('select#form_other_title')
113
113
  end
114
114
 
115
115
  it 'supports match_xpath expectations' do
116
- find(:select, 'form_title').must_match_xpath('.//select[@id="form_title"]')
117
- find(:select, 'form_title').wont_match_xpath('.//select[@id="not_on_page"]')
116
+ _(find(:select, 'form_title')).must_match_xpath('.//select[@id="form_title"]')
117
+ _(find(:select, 'form_title')).wont_match_xpath('.//select[@id="not_on_page"]')
118
118
  end
119
119
 
120
120
  it 'handles failures' do
121
- page.must_have_select('non_existing_form_title')
121
+ _(page).must_have_select('non_existing_form_title')
122
122
  end
123
123
 
124
124
  it 'supports style expectations' do
125
125
  skip "Rack test doesn't support style" if Capybara.current_driver == :rack_test
126
126
  visit('/with_html')
127
- find(:css, '#second').must_have_style('display' => 'inline') # deprecated
128
- find(:css, '#second').must_match_style('display' => 'inline')
127
+ _(find(:css, '#second')).must_have_style('display' => 'inline') # deprecated
128
+ _(find(:css, '#second')).must_match_style('display' => 'inline')
129
129
  end
130
130
 
131
131
  it 'supports ancestor expectations' do
132
132
  option = find(:option, 'Finnish')
133
- option.must_have_ancestor(:css, '#form_locale')
133
+ _(option).must_have_ancestor(:css, '#form_locale')
134
134
  end
135
135
 
136
136
  it 'supports sibling expectations' do
137
137
  option = find(:css, '#form_title').find(:option, 'Mrs')
138
- option.must_have_sibling(:option, 'Mr')
138
+ _(option).must_have_sibling(:option, 'Mr')
139
139
  end
140
140
  end
141
141