capybara 3.32.0 → 3.33.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.
- checksums.yaml +4 -4
- data/History.md +38 -1
- data/README.md +10 -3
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/minitest.rb +2 -3
- data/lib/capybara/node/actions.rb +16 -20
- data/lib/capybara/node/matchers.rb +4 -6
- data/lib/capybara/queries/selector_query.rb +8 -1
- data/lib/capybara/queries/style_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +6 -0
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/servers.rb +1 -1
- data/lib/capybara/result.rb +4 -1
- data/lib/capybara/rspec/matchers/have_text.rb +1 -1
- data/lib/capybara/selector/definition/button.rb +1 -0
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/link.rb +8 -0
- data/lib/capybara/selector/definition/table.rb +1 -1
- data/lib/capybara/selector/definition.rb +5 -4
- data/lib/capybara/selector/selector.rb +4 -0
- data/lib/capybara/selector.rb +10 -1
- data/lib/capybara/selenium/driver.rb +6 -4
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +7 -9
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +7 -9
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -2
- data/lib/capybara/selenium/node.rb +17 -3
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/selenium/patches/action_pauser.rb +4 -1
- data/lib/capybara/selenium/patches/logs.rb +3 -5
- data/lib/capybara/session/config.rb +3 -1
- data/lib/capybara/session.rb +3 -3
- data/lib/capybara/spec/public/test.js +7 -0
- data/lib/capybara/spec/session/click_button_spec.rb +11 -0
- data/lib/capybara/spec/session/has_button_spec.rb +16 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
- data/lib/capybara/spec/session/has_field_spec.rb +16 -0
- data/lib/capybara/spec/session/has_select_spec.rb +4 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
- data/lib/capybara/spec/session/node_spec.rb +6 -6
- data/lib/capybara/spec/spec_helper.rb +1 -0
- data/lib/capybara/spec/test_app.rb +14 -18
- data/lib/capybara/spec/views/form.erb +6 -1
- data/lib/capybara/spec/views/with_dragula.erb +3 -1
- data/lib/capybara/spec/views/with_js.erb +1 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara.rb +17 -7
- data/spec/capybara_spec.rb +1 -1
- data/spec/dsl_spec.rb +14 -1
- data/spec/minitest_spec.rb +1 -1
- data/spec/rack_test_spec.rb +1 -0
- data/spec/result_spec.rb +1 -17
- data/spec/rspec/shared_spec_matchers.rb +65 -53
- data/spec/selector_spec.rb +1 -1
- data/spec/selenium_spec_chrome.rb +0 -2
- data/spec/server_spec.rb +41 -49
- data/spec/shared_selenium_node.rb +10 -0
- data/spec/shared_selenium_session.rb +25 -7
- data/spec/spec_helper.rb +1 -1
- metadata +4 -3
|
@@ -89,29 +89,29 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
89
89
|
|
|
90
90
|
context 'on a page or node' do
|
|
91
91
|
before do
|
|
92
|
-
visit('/with_html')
|
|
92
|
+
session.visit('/with_html')
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
context 'with should' do
|
|
96
96
|
it 'passes if has_css? returns true' do
|
|
97
|
-
expect(
|
|
97
|
+
expect(session).to have_css('h1')
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it 'fails if has_css? returns false' do
|
|
101
101
|
expect do
|
|
102
|
-
expect(
|
|
102
|
+
expect(session).to have_css('h1#doesnotexist')
|
|
103
103
|
end.to raise_error(/expected to find css "h1#doesnotexist" but there were no matches/)
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
context 'with should_not' do
|
|
108
108
|
it 'passes if has_no_css? returns true' do
|
|
109
|
-
expect(
|
|
109
|
+
expect(session).not_to have_css('h1#doesnotexist')
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
it 'fails if has_no_css? returns false' do
|
|
113
113
|
expect do
|
|
114
|
-
expect(
|
|
114
|
+
expect(session).not_to have_css('h1')
|
|
115
115
|
end.to raise_error(/expected not to find visible css "h1"/)
|
|
116
116
|
end
|
|
117
117
|
end
|
|
@@ -158,29 +158,29 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
158
158
|
|
|
159
159
|
context 'on a page or node' do
|
|
160
160
|
before do
|
|
161
|
-
visit('/with_html')
|
|
161
|
+
session.visit('/with_html')
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
context 'with should' do
|
|
165
165
|
it 'passes if has_xpath? returns true' do
|
|
166
|
-
expect(
|
|
166
|
+
expect(session).to have_xpath('//h1')
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
it 'fails if has_xpath? returns false' do
|
|
170
170
|
expect do
|
|
171
|
-
expect(
|
|
171
|
+
expect(session).to have_xpath("//h1[@id='doesnotexist']")
|
|
172
172
|
end.to raise_error(%r{expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches})
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
context 'with should_not' do
|
|
177
177
|
it 'passes if has_no_xpath? returns true' do
|
|
178
|
-
expect(
|
|
178
|
+
expect(session).not_to have_xpath('//h1[@id="doesnotexist"]')
|
|
179
179
|
end
|
|
180
180
|
|
|
181
181
|
it 'fails if has_no_xpath? returns false' do
|
|
182
182
|
expect do
|
|
183
|
-
expect(
|
|
183
|
+
expect(session).not_to have_xpath('//h1')
|
|
184
184
|
end.to raise_error(%r{expected not to find visible xpath "//h1"})
|
|
185
185
|
end
|
|
186
186
|
end
|
|
@@ -222,35 +222,35 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
222
222
|
|
|
223
223
|
context 'on a page or node' do
|
|
224
224
|
before do
|
|
225
|
-
visit('/with_html')
|
|
225
|
+
session.visit('/with_html')
|
|
226
226
|
end
|
|
227
227
|
|
|
228
228
|
context 'with should' do
|
|
229
229
|
it 'passes if has_selector? returns true' do
|
|
230
|
-
expect(
|
|
230
|
+
expect(session).to have_selector('//h1', text: 'test')
|
|
231
231
|
end
|
|
232
232
|
|
|
233
233
|
it 'fails if has_selector? returns false' do
|
|
234
234
|
expect do
|
|
235
|
-
expect(
|
|
235
|
+
expect(session).to have_selector("//h1[@id='doesnotexist']")
|
|
236
236
|
end.to raise_error(%r{expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches})
|
|
237
237
|
end
|
|
238
238
|
|
|
239
239
|
it 'includes text in error message' do
|
|
240
240
|
expect do
|
|
241
|
-
expect(
|
|
241
|
+
expect(session).to have_selector('//h1', text: 'wrong text')
|
|
242
242
|
end.to raise_error(%r{expected to find visible xpath "//h1" with text "wrong text" but there were no matches})
|
|
243
243
|
end
|
|
244
244
|
end
|
|
245
245
|
|
|
246
246
|
context 'with should_not' do
|
|
247
247
|
it 'passes if has_no_css? returns true' do
|
|
248
|
-
expect(
|
|
248
|
+
expect(session).not_to have_selector(:css, 'h1#doesnotexist')
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
it 'fails if has_no_selector? returns false' do
|
|
252
252
|
expect do
|
|
253
|
-
expect(
|
|
253
|
+
expect(session).not_to have_selector(:css, 'h1', text: 'test')
|
|
254
254
|
end.to raise_error(/expected not to find visible css "h1" with text "test"/)
|
|
255
255
|
end
|
|
256
256
|
end
|
|
@@ -265,7 +265,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
265
265
|
|
|
266
266
|
describe 'have_content matcher' do
|
|
267
267
|
it 'gives proper description' do
|
|
268
|
-
expect(have_content('Text').description).to eq('text "Text"')
|
|
268
|
+
expect(have_content('Text').description).to eq('have text "Text"')
|
|
269
269
|
end
|
|
270
270
|
|
|
271
271
|
context 'on a string' do
|
|
@@ -304,21 +304,21 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
304
304
|
|
|
305
305
|
context 'on a page or node' do
|
|
306
306
|
before do
|
|
307
|
-
visit('/with_html')
|
|
307
|
+
session.visit('/with_html')
|
|
308
308
|
end
|
|
309
309
|
|
|
310
310
|
context 'with should' do
|
|
311
311
|
it 'passes if has_content? returns true' do
|
|
312
|
-
expect(
|
|
312
|
+
expect(session).to have_content('This is a test')
|
|
313
313
|
end
|
|
314
314
|
|
|
315
315
|
it 'passes if has_content? returns true using regexp' do
|
|
316
|
-
expect(
|
|
316
|
+
expect(session).to have_content(/test/)
|
|
317
317
|
end
|
|
318
318
|
|
|
319
319
|
it 'fails if has_content? returns false' do
|
|
320
320
|
expect do
|
|
321
|
-
expect(
|
|
321
|
+
expect(session).to have_content('No such Text')
|
|
322
322
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
323
323
|
end
|
|
324
324
|
|
|
@@ -329,7 +329,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
329
329
|
|
|
330
330
|
it 'fails if has_content? returns false' do
|
|
331
331
|
expect do
|
|
332
|
-
expect(
|
|
332
|
+
expect(session).to have_content('No such Text')
|
|
333
333
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
334
334
|
end
|
|
335
335
|
end
|
|
@@ -337,14 +337,26 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
337
337
|
|
|
338
338
|
context 'with should_not' do
|
|
339
339
|
it 'passes if has_no_content? returns true' do
|
|
340
|
-
expect(
|
|
340
|
+
expect(session).not_to have_content('No such Text')
|
|
341
341
|
end
|
|
342
342
|
|
|
343
343
|
it 'fails if has_no_content? returns false' do
|
|
344
344
|
expect do
|
|
345
|
-
expect(
|
|
345
|
+
expect(session).not_to have_content('This is a test')
|
|
346
346
|
end.to raise_error(/expected not to find text "This is a test"/)
|
|
347
347
|
end
|
|
348
|
+
|
|
349
|
+
it 'not_to have_content behaves the same as to have_no_content' do
|
|
350
|
+
Capybara.using_wait_time(5) do
|
|
351
|
+
expect(session).to have_content('This is a test')
|
|
352
|
+
start = Time.now
|
|
353
|
+
expect(session).to have_no_content('No such Text')
|
|
354
|
+
to_time = Time.now
|
|
355
|
+
expect(session).not_to have_content('No such Text')
|
|
356
|
+
not_to_time = Time.now
|
|
357
|
+
expect(not_to_time - to_time).to be_within(0.5).of(to_time - start)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
348
360
|
end
|
|
349
361
|
end
|
|
350
362
|
|
|
@@ -357,7 +369,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
357
369
|
|
|
358
370
|
describe 'have_text matcher' do
|
|
359
371
|
it 'gives proper description' do
|
|
360
|
-
expect(have_text('Text').description).to eq('text "Text"')
|
|
372
|
+
expect(have_text('Text').description).to eq('have text "Text"')
|
|
361
373
|
end
|
|
362
374
|
|
|
363
375
|
context 'on a string' do
|
|
@@ -432,30 +444,30 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
432
444
|
|
|
433
445
|
context 'on a page or node' do
|
|
434
446
|
before do
|
|
435
|
-
visit('/with_html')
|
|
447
|
+
session.visit('/with_html')
|
|
436
448
|
end
|
|
437
449
|
|
|
438
450
|
context 'with should' do
|
|
439
451
|
it 'passes if has_text? returns true' do
|
|
440
|
-
expect(
|
|
452
|
+
expect(session).to have_text('This is a test')
|
|
441
453
|
end
|
|
442
454
|
|
|
443
455
|
it 'passes if has_text? returns true using regexp' do
|
|
444
|
-
expect(
|
|
456
|
+
expect(session).to have_text(/test/)
|
|
445
457
|
end
|
|
446
458
|
|
|
447
459
|
it 'can check for all text' do
|
|
448
|
-
expect(
|
|
460
|
+
expect(session).to have_text(:all, 'Some of this text is hidden!')
|
|
449
461
|
end
|
|
450
462
|
|
|
451
463
|
it 'can check for visible text' do
|
|
452
|
-
expect(
|
|
453
|
-
expect(
|
|
464
|
+
expect(session).to have_text(:visible, 'Some of this text is')
|
|
465
|
+
expect(session).not_to have_text(:visible, 'Some of this text is hidden!')
|
|
454
466
|
end
|
|
455
467
|
|
|
456
468
|
it 'fails if has_text? returns false' do
|
|
457
469
|
expect do
|
|
458
|
-
expect(
|
|
470
|
+
expect(session).to have_text('No such Text')
|
|
459
471
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
460
472
|
end
|
|
461
473
|
|
|
@@ -466,7 +478,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
466
478
|
|
|
467
479
|
it 'fails if has_text? returns false' do
|
|
468
480
|
expect do
|
|
469
|
-
expect(
|
|
481
|
+
expect(session).to have_text('No such Text')
|
|
470
482
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
471
483
|
end
|
|
472
484
|
end
|
|
@@ -474,12 +486,12 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
474
486
|
|
|
475
487
|
context 'with should_not' do
|
|
476
488
|
it 'passes if has_no_text? returns true' do
|
|
477
|
-
expect(
|
|
489
|
+
expect(session).not_to have_text('No such Text')
|
|
478
490
|
end
|
|
479
491
|
|
|
480
492
|
it 'fails if has_no_text? returns false' do
|
|
481
493
|
expect do
|
|
482
|
-
expect(
|
|
494
|
+
expect(session).not_to have_text('This is a test')
|
|
483
495
|
end.to raise_error(/expected not to find text "This is a test"/)
|
|
484
496
|
end
|
|
485
497
|
end
|
|
@@ -542,15 +554,15 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
542
554
|
|
|
543
555
|
context 'on a page or node' do
|
|
544
556
|
it 'passes if there is such a title' do
|
|
545
|
-
visit('/with_js')
|
|
546
|
-
expect(
|
|
557
|
+
session.visit('/with_js')
|
|
558
|
+
expect(session).to have_title('with_js')
|
|
547
559
|
end
|
|
548
560
|
|
|
549
561
|
it 'fails if there is no such title' do
|
|
550
|
-
visit('/with_js')
|
|
562
|
+
session.visit('/with_js')
|
|
551
563
|
expect do
|
|
552
|
-
expect(
|
|
553
|
-
end.to raise_error(
|
|
564
|
+
expect(session).to have_title('No such title')
|
|
565
|
+
end.to raise_error(/ to include "No such title"/)
|
|
554
566
|
end
|
|
555
567
|
|
|
556
568
|
context 'with wait' do
|
|
@@ -560,14 +572,14 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
560
572
|
|
|
561
573
|
it 'waits if wait time is more than timeout' do
|
|
562
574
|
session.click_link('Change title')
|
|
563
|
-
using_wait_time 0 do
|
|
575
|
+
session.using_wait_time 0 do
|
|
564
576
|
expect(session).to have_title('changed title', wait: 2)
|
|
565
577
|
end
|
|
566
578
|
end
|
|
567
579
|
|
|
568
580
|
it "doesn't wait if wait time is less than timeout" do
|
|
569
581
|
session.click_link('Change title')
|
|
570
|
-
using_wait_time 3 do
|
|
582
|
+
session.using_wait_time 3 do
|
|
571
583
|
expect(session).not_to have_title('changed title', wait: 0)
|
|
572
584
|
end
|
|
573
585
|
end
|
|
@@ -586,15 +598,15 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
586
598
|
|
|
587
599
|
context 'on a page or node' do
|
|
588
600
|
it 'passes if there is such a current path' do
|
|
589
|
-
visit('/with_js')
|
|
590
|
-
expect(
|
|
601
|
+
session.visit('/with_js')
|
|
602
|
+
expect(session).to have_current_path('/with_js')
|
|
591
603
|
end
|
|
592
604
|
|
|
593
605
|
it 'fails if there is no such current_path' do
|
|
594
606
|
visit('/with_js')
|
|
595
607
|
expect do
|
|
596
|
-
expect(
|
|
597
|
-
end.to raise_error(
|
|
608
|
+
expect(session).to have_current_path('/not_with_js')
|
|
609
|
+
end.to raise_error(%r{to equal "/not_with_js"})
|
|
598
610
|
end
|
|
599
611
|
|
|
600
612
|
context 'with wait' do
|
|
@@ -604,14 +616,14 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
604
616
|
|
|
605
617
|
it 'waits if wait time is more than timeout' do
|
|
606
618
|
session.click_link('Change page')
|
|
607
|
-
using_wait_time 0 do
|
|
619
|
+
session.using_wait_time 0 do
|
|
608
620
|
expect(session).to have_current_path('/with_html', wait: 2)
|
|
609
621
|
end
|
|
610
622
|
end
|
|
611
623
|
|
|
612
624
|
it "doesn't wait if wait time is less than timeout" do
|
|
613
625
|
session.click_link('Change page')
|
|
614
|
-
using_wait_time 0 do
|
|
626
|
+
session.using_wait_time 0 do
|
|
615
627
|
expect(session).not_to have_current_path('/with_html')
|
|
616
628
|
end
|
|
617
629
|
end
|
|
@@ -619,8 +631,8 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
619
631
|
end
|
|
620
632
|
|
|
621
633
|
it 'supports compounding' do
|
|
622
|
-
visit('/with_html')
|
|
623
|
-
expect(
|
|
634
|
+
session.visit('/with_html')
|
|
635
|
+
expect(session).to have_current_path('/not_with_html').or have_current_path('/with_html')
|
|
624
636
|
end
|
|
625
637
|
end
|
|
626
638
|
|
|
@@ -828,10 +840,10 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
828
840
|
end
|
|
829
841
|
|
|
830
842
|
it 'gives proper description when :visible option passed' do
|
|
831
|
-
expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"')
|
|
843
|
+
expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
|
832
844
|
expect(have_table('Lovely table', visible: :hidden).description).to eq('have non-visible table "Lovely table"')
|
|
833
845
|
expect(have_table('Lovely table', visible: :all).description).to eq('have table "Lovely table"')
|
|
834
|
-
expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"')
|
|
846
|
+
expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
|
835
847
|
end
|
|
836
848
|
|
|
837
849
|
it 'passes if there is such a table' do
|
|
@@ -859,7 +871,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
|
859
871
|
|
|
860
872
|
describe '#and' do
|
|
861
873
|
it "should run 'concurrently'" do
|
|
862
|
-
|
|
874
|
+
session.using_wait_time(2) do
|
|
863
875
|
matcher = have_text('this is not there').and have_text('neither is this')
|
|
864
876
|
expect(Benchmark.realtime do
|
|
865
877
|
expect do
|
data/spec/selector_spec.rb
CHANGED
|
@@ -476,7 +476,7 @@ RSpec.describe Capybara do
|
|
|
476
476
|
end
|
|
477
477
|
|
|
478
478
|
describe ':link_or_button selector' do
|
|
479
|
-
around
|
|
479
|
+
around do |example|
|
|
480
480
|
described_class.modify_selector(:link_or_button) do
|
|
481
481
|
expression_filter(:random) { |xpath, _| xpath } # do nothing filter
|
|
482
482
|
end
|
|
@@ -70,8 +70,6 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
|
|
|
70
70
|
pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
|
|
71
71
|
when /Capybara::Window#fullscreen should be able to fullscreen the window/
|
|
72
72
|
skip 'Chromedriver hangs on attempts to fullscreen in headless mode' if ENV['HEADLESS']
|
|
73
|
-
when /details non-summary descendants should be non-visible/
|
|
74
|
-
pending 'Chromedriver built-in is_displayed is currently broken' if ENV['W3C'] == 'false'
|
|
75
73
|
when /node #right_click delay should delay the mouse up/
|
|
76
74
|
skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
|
|
77
75
|
end
|
data/spec/server_spec.rb
CHANGED
|
@@ -75,25 +75,21 @@ RSpec.describe Capybara::Server do
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
it 'should handle that getting available ports fails randomly' do
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
begin
|
|
86
|
-
call_count.zero? ? d_server : m.call(*args)
|
|
87
|
-
ensure
|
|
88
|
-
call_count += 1
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
port = described_class.new(Object.new, host: '0.0.0.0').port
|
|
93
|
-
expect(port).not_to eq(server_port)
|
|
78
|
+
# Use a port to force a EADDRINUSE error to be generated
|
|
79
|
+
server = TCPServer.new('0.0.0.0', 0)
|
|
80
|
+
server_port = server.addr[1]
|
|
81
|
+
d_server = instance_double('TCPServer', addr: [nil, server_port, nil, nil], close: nil)
|
|
82
|
+
call_count = 0
|
|
83
|
+
allow(TCPServer).to receive(:new).and_wrap_original do |m, *args|
|
|
84
|
+
call_count.zero? ? d_server : m.call(*args)
|
|
94
85
|
ensure
|
|
95
|
-
|
|
86
|
+
call_count += 1
|
|
96
87
|
end
|
|
88
|
+
|
|
89
|
+
port = described_class.new(Object.new, host: '0.0.0.0').port
|
|
90
|
+
expect(port).not_to eq(server_port)
|
|
91
|
+
ensure
|
|
92
|
+
server&.close
|
|
97
93
|
end
|
|
98
94
|
|
|
99
95
|
it 'should return its #base_url' do
|
|
@@ -104,29 +100,27 @@ RSpec.describe Capybara::Server do
|
|
|
104
100
|
end
|
|
105
101
|
|
|
106
102
|
it 'should support SSL' do
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
server = described_class.new(app).boot
|
|
113
|
-
|
|
114
|
-
expect do
|
|
115
|
-
Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
|
|
116
|
-
end.to(raise_error do |e|
|
|
117
|
-
expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
|
|
118
|
-
end)
|
|
103
|
+
key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
|
|
104
|
+
cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
|
|
105
|
+
Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
|
|
106
|
+
app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
|
|
107
|
+
server = described_class.new(app).boot
|
|
119
108
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
109
|
+
expect do
|
|
110
|
+
Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
|
|
111
|
+
end.to(raise_error do |e|
|
|
112
|
+
expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
|
|
113
|
+
end)
|
|
123
114
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
|
|
127
|
-
ensure
|
|
128
|
-
Capybara.server = :default
|
|
115
|
+
res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
|
|
116
|
+
https.get('/')
|
|
129
117
|
end
|
|
118
|
+
|
|
119
|
+
expect(res.body).to include('Hello SSL Server!')
|
|
120
|
+
uri = ::Addressable::URI.parse(server.base_url)
|
|
121
|
+
expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
|
|
122
|
+
ensure
|
|
123
|
+
Capybara.server = :default
|
|
130
124
|
end
|
|
131
125
|
|
|
132
126
|
context 'When Capybara.reuse_server is true' do
|
|
@@ -224,19 +218,17 @@ RSpec.describe Capybara::Server do
|
|
|
224
218
|
end
|
|
225
219
|
|
|
226
220
|
it 'should raise server errors when the server errors before the timeout' do
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
raise 'kaboom'
|
|
231
|
-
end
|
|
232
|
-
Capybara.server = :kaboom
|
|
233
|
-
|
|
234
|
-
expect do
|
|
235
|
-
described_class.new(proc { |e| }).boot
|
|
236
|
-
end.to raise_error(RuntimeError, 'kaboom')
|
|
237
|
-
ensure
|
|
238
|
-
Capybara.server = :default
|
|
221
|
+
Capybara.register_server :kaboom do
|
|
222
|
+
sleep 0.1
|
|
223
|
+
raise 'kaboom'
|
|
239
224
|
end
|
|
225
|
+
Capybara.server = :kaboom
|
|
226
|
+
|
|
227
|
+
expect do
|
|
228
|
+
described_class.new(proc { |e| }).boot
|
|
229
|
+
end.to raise_error(RuntimeError, 'kaboom')
|
|
230
|
+
ensure
|
|
231
|
+
Capybara.server = :default
|
|
240
232
|
end
|
|
241
233
|
|
|
242
234
|
it 'should raise an error when there are pending requests' do
|
|
@@ -35,6 +35,16 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
describe '#set' do
|
|
39
|
+
it 'respects maxlength when using rapid set' do
|
|
40
|
+
session.visit('/form')
|
|
41
|
+
inp = session.find(:css, '#long_length')
|
|
42
|
+
value = (0...50).map { |i| ((i % 26) + 65).chr }.join
|
|
43
|
+
inp.set(value, rapid: true)
|
|
44
|
+
expect(inp.value).to eq value[0...35]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
38
48
|
describe '#visible?' do
|
|
39
49
|
let(:bridge) do
|
|
40
50
|
session.driver.browser.send(:bridge)
|
|
@@ -160,6 +160,15 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
|
160
160
|
fill_options: { clear: :none })
|
|
161
161
|
expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
|
|
162
162
|
end
|
|
163
|
+
|
|
164
|
+
it 'works with rapid fill' do
|
|
165
|
+
pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
|
|
166
|
+
|
|
167
|
+
long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
|
|
168
|
+
session.visit('/form')
|
|
169
|
+
session.fill_in('form_first_name', with: long_string, fill_options: { clear: :none })
|
|
170
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('John' + long_string)
|
|
171
|
+
end
|
|
163
172
|
end
|
|
164
173
|
|
|
165
174
|
describe '#fill_in with Date' do
|
|
@@ -425,7 +434,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
|
425
434
|
it 'can find html5 svg elements' do
|
|
426
435
|
session.visit('with_html5_svg')
|
|
427
436
|
expect(session).to have_selector(:element, :svg)
|
|
428
|
-
expect(session).to have_selector(:element, :rect, visible:
|
|
437
|
+
expect(session).to have_selector(:element, :rect, visible: :visible)
|
|
429
438
|
expect(session).to have_selector(:element, :circle)
|
|
430
439
|
expect(session).to have_selector(:element, :linearGradient, visible: :all)
|
|
431
440
|
end
|
|
@@ -441,21 +450,30 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
|
441
450
|
context 'controlled components' do
|
|
442
451
|
it 'can set and clear a text field' do
|
|
443
452
|
skip "This test doesn't support older browsers" if ie?(session)
|
|
444
|
-
|
|
445
|
-
# session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
|
|
446
|
-
# copied into local view
|
|
453
|
+
|
|
447
454
|
session.visit 'react'
|
|
448
|
-
|
|
449
|
-
# session.within_frame(:css, 'iframe.result-iframe:not([src=""])', wait: 10) do
|
|
455
|
+
|
|
450
456
|
session.fill_in('Name:', with: 'abc')
|
|
451
457
|
session.accept_prompt 'A name was submitted: abc' do
|
|
452
458
|
session.click_button('Submit')
|
|
453
459
|
end
|
|
460
|
+
|
|
454
461
|
session.fill_in('Name:', with: '')
|
|
455
462
|
session.accept_prompt(/A name was submitted: $/) do
|
|
456
463
|
session.click_button('Submit')
|
|
457
464
|
end
|
|
458
|
-
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it 'works with rapid fill' do
|
|
468
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
469
|
+
|
|
470
|
+
session.visit 'react'
|
|
471
|
+
long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
|
|
472
|
+
|
|
473
|
+
session.fill_in('Name:', with: long_string)
|
|
474
|
+
session.accept_prompt "A name was submitted: #{long_string}" do
|
|
475
|
+
session.click_button('Submit')
|
|
476
|
+
end
|
|
459
477
|
end
|
|
460
478
|
end
|
|
461
479
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: capybara
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.33.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Walpole
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain:
|
|
12
12
|
- gem-public_cert.pem
|
|
13
|
-
date: 2020-
|
|
13
|
+
date: 2020-06-21 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: addressable
|
|
@@ -450,6 +450,7 @@ files:
|
|
|
450
450
|
- lib/capybara/rack_test/form.rb
|
|
451
451
|
- lib/capybara/rack_test/node.rb
|
|
452
452
|
- lib/capybara/rails.rb
|
|
453
|
+
- lib/capybara/registration_container.rb
|
|
453
454
|
- lib/capybara/registrations/drivers.rb
|
|
454
455
|
- lib/capybara/registrations/patches/puma_ssl.rb
|
|
455
456
|
- lib/capybara/registrations/servers.rb
|
|
@@ -738,7 +739,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
738
739
|
requirements:
|
|
739
740
|
- - ">="
|
|
740
741
|
- !ruby/object:Gem::Version
|
|
741
|
-
version: 2.
|
|
742
|
+
version: 2.5.0
|
|
742
743
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
743
744
|
requirements:
|
|
744
745
|
- - ">="
|