capybara 3.20.2 → 3.22.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/.yardopts +1 -0
- data/History.md +28 -0
- data/README.md +16 -11
- data/lib/capybara/driver/node.rb +6 -2
- data/lib/capybara/helpers.rb +1 -1
- data/lib/capybara/minitest/spec.rb +20 -7
- data/lib/capybara/minitest.rb +18 -5
- data/lib/capybara/node/actions.rb +36 -29
- data/lib/capybara/node/element.rb +123 -82
- data/lib/capybara/node/finders.rb +42 -53
- data/lib/capybara/node/matchers.rb +161 -72
- data/lib/capybara/queries/ancestor_query.rb +9 -7
- data/lib/capybara/queries/sibling_query.rb +11 -4
- data/lib/capybara/result.rb +2 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +30 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +30 -0
- data/lib/capybara/rspec/matchers.rb +16 -1
- data/lib/capybara/selector/definition/checkbox.rb +8 -5
- data/lib/capybara/selector/definition/css.rb +4 -1
- data/lib/capybara/selector/definition/radio_button.rb +8 -5
- data/lib/capybara/selector/filter_set.rb +4 -2
- data/lib/capybara/selector/regexp_disassembler.rb +2 -2
- data/lib/capybara/selector.rb +153 -171
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +35 -1
- data/lib/capybara/selenium/extensions/html5_drag.rb +63 -0
- data/lib/capybara/selenium/node.rb +4 -0
- data/lib/capybara/selenium/nodes/chrome_node.rb +4 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +4 -13
- data/lib/capybara/selenium/nodes/ie_node.rb +14 -3
- data/lib/capybara/selenium/nodes/safari_node.rb +0 -13
- data/lib/capybara/session/config.rb +1 -1
- data/lib/capybara/session.rb +74 -71
- data/lib/capybara/spec/public/test.js +29 -3
- data/lib/capybara/spec/session/attach_file_spec.rb +13 -5
- data/lib/capybara/spec/session/check_spec.rb +6 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/has_ancestor_spec.rb +44 -0
- data/lib/capybara/spec/session/has_css_spec.rb +4 -3
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/node_spec.rb +85 -0
- data/lib/capybara/spec/session/select_spec.rb +5 -5
- data/lib/capybara/spec/spec_helper.rb +4 -0
- data/lib/capybara/spec/views/form.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +10 -10
- data/lib/capybara.rb +42 -36
- data/spec/minitest_spec.rb +11 -1
- data/spec/minitest_spec_spec.rb +11 -1
- data/spec/regexp_dissassembler_spec.rb +1 -1
- data/spec/selenium_spec_firefox.rb +2 -0
- data/spec/selenium_spec_ie.rb +13 -7
- data/spec/selenium_spec_safari.rb +2 -0
- data/spec/shared_selenium_session.rb +1 -51
- metadata +9 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Capybara::SpecHelper.spec '#have_sibling' do
|
|
4
|
+
before do
|
|
5
|
+
@session.visit('/with_html')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'should assert a prior sibling element using the given locator' do
|
|
9
|
+
el = @session.find(:css, '#mid_sibling')
|
|
10
|
+
expect(el).to have_sibling(:css, '#pre_sibling')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should assert a following sibling element using the given locator' do
|
|
14
|
+
el = @session.find(:css, '#mid_sibling')
|
|
15
|
+
expect(el).to have_sibling(:css, '#post_sibling')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should not raise an error if there are multiple matches' do
|
|
19
|
+
el = @session.find(:css, '#mid_sibling')
|
|
20
|
+
expect(el).to have_sibling(:css, 'div')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should allow counts to be specified' do
|
|
24
|
+
el = @session.find(:css, '#mid_sibling')
|
|
25
|
+
|
|
26
|
+
expect(el).to have_sibling(:css, 'div').exactly(2).times
|
|
27
|
+
expect do
|
|
28
|
+
expect(el).to have_sibling(:css, 'div').once
|
|
29
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Capybara::SpecHelper.spec '#have_no_sibling' do
|
|
34
|
+
before do
|
|
35
|
+
@session.visit('/with_html')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should assert no matching sibling' do
|
|
39
|
+
el = @session.find(:css, '#mid_sibling')
|
|
40
|
+
expect(el).to have_no_sibling(:css, '#not_a_sibling')
|
|
41
|
+
expect(el).not_to have_sibling(:css, '#not_a_sibling')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should raise if there are matching siblings' do
|
|
45
|
+
el = @session.find(:css, '#mid_sibling')
|
|
46
|
+
expect do
|
|
47
|
+
expect(el).to have_no_sibling(:css, '#pre_sibling')
|
|
48
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -242,6 +242,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
242
242
|
expect(@session.find('//div[@id="hidden_attr"]')).not_to be_visible
|
|
243
243
|
expect(@session.find('//a[@id="hidden_attr_via_ancestor"]')).not_to be_visible
|
|
244
244
|
expect(@session.find('//input[@id="hidden_input"]')).not_to be_visible
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it 'template elements should not be visible' do
|
|
248
|
+
Capybara.ignore_hidden_elements = false
|
|
245
249
|
expect(@session.find('//template')).not_to be_visible
|
|
246
250
|
end
|
|
247
251
|
|
|
@@ -414,6 +418,87 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
414
418
|
link.drag_to target
|
|
415
419
|
expect(@session).to have_xpath('//div[contains(., "Dropped!")]')
|
|
416
420
|
end
|
|
421
|
+
|
|
422
|
+
context 'HTML5', requires: %i[js html5_drag] do
|
|
423
|
+
it 'should HTML5 drag and drop an object' do
|
|
424
|
+
@session.visit('/with_js')
|
|
425
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
426
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
427
|
+
element.drag_to(target)
|
|
428
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it 'should set clientX/Y in dragover events' do
|
|
432
|
+
@session.visit('/with_js')
|
|
433
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
434
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
435
|
+
element.drag_to(target)
|
|
436
|
+
expect(@session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
it 'should not HTML5 drag and drop on a non HTML5 drop element' do
|
|
440
|
+
@session.visit('/with_js')
|
|
441
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
442
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
443
|
+
target.execute_script("$(this).removeClass('drop');")
|
|
444
|
+
element.drag_to(target)
|
|
445
|
+
sleep 1
|
|
446
|
+
expect(@session).not_to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it 'should HTML5 drag and drop when scrolling needed' do
|
|
450
|
+
@session.visit('/with_js')
|
|
451
|
+
element = @session.find('//div[@id="drag_html5_scroll"]')
|
|
452
|
+
target = @session.find('//div[@id="drop_html5_scroll"]')
|
|
453
|
+
element.drag_to(target)
|
|
454
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5_scroll")]')
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it 'should drag HTML5 default draggable elements' do
|
|
458
|
+
@session.visit('/with_js')
|
|
459
|
+
link = @session.find_link('drag_link_html5')
|
|
460
|
+
target = @session.find(:id, 'drop_html5')
|
|
461
|
+
link.drag_to target
|
|
462
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
describe 'Element#drop', requires: %i[js html5_drag] do
|
|
468
|
+
it 'can drop a file' do
|
|
469
|
+
@session.visit('/with_js')
|
|
470
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
471
|
+
target.drop(
|
|
472
|
+
with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__)))
|
|
473
|
+
)
|
|
474
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
it 'can drop multiple files' do
|
|
478
|
+
@session.visit('/with_js')
|
|
479
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
480
|
+
target.drop(
|
|
481
|
+
with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))),
|
|
482
|
+
with_os_path_separators(File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__)))
|
|
483
|
+
)
|
|
484
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
|
|
485
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: test_file.txt")]')
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
it 'can drop strings' do
|
|
489
|
+
@session.visit('/with_js')
|
|
490
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
491
|
+
target.drop('text/plain' => 'Some dropped text')
|
|
492
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
it 'can drop multiple strings' do
|
|
496
|
+
@session.visit('/with_js')
|
|
497
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
498
|
+
target.drop('text/plain' => 'Some dropped text', 'text/url' => 'http://www.google.com')
|
|
499
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
|
|
500
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/url http://www.google.com")]')
|
|
501
|
+
end
|
|
417
502
|
end
|
|
418
503
|
|
|
419
504
|
describe '#hover', requires: [:hover] do
|
|
@@ -42,13 +42,13 @@ Capybara::SpecHelper.spec '#select' do
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it 'should select an option from a select box by id' do
|
|
45
|
-
@session.select('
|
|
45
|
+
@session.select('Finnish', from: 'form_locale')
|
|
46
46
|
@session.click_button('awesome')
|
|
47
47
|
expect(extract_results(@session)['locale']).to eq('fi')
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
it 'should select an option from a select box by label' do
|
|
51
|
-
@session.select('
|
|
51
|
+
@session.select('Finnish', from: 'Locale')
|
|
52
52
|
@session.click_button('awesome')
|
|
53
53
|
expect(extract_results(@session)['locale']).to eq('fi')
|
|
54
54
|
end
|
|
@@ -183,7 +183,7 @@ Capybara::SpecHelper.spec '#select' do
|
|
|
183
183
|
context 'with :exact option' do
|
|
184
184
|
context 'when `false`' do
|
|
185
185
|
it 'can match select box approximately' do
|
|
186
|
-
@session.select('
|
|
186
|
+
@session.select('Finnish', from: 'Loc', exact: false)
|
|
187
187
|
@session.click_button('awesome')
|
|
188
188
|
expect(extract_results(@session)['locale']).to eq('fi')
|
|
189
189
|
end
|
|
@@ -204,13 +204,13 @@ Capybara::SpecHelper.spec '#select' do
|
|
|
204
204
|
context 'when `true`' do
|
|
205
205
|
it 'can match select box approximately' do
|
|
206
206
|
expect do
|
|
207
|
-
@session.select('
|
|
207
|
+
@session.select('Finnish', from: 'Loc', exact: true)
|
|
208
208
|
end.to raise_error(Capybara::ElementNotFound)
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it 'can match option approximately' do
|
|
212
212
|
expect do
|
|
213
|
-
@session.select('Fin', from: 'Locale', exact:
|
|
213
|
+
@session.select('Fin', from: 'Locale', exact: true)
|
|
214
214
|
end.to raise_error(Capybara::ElementNotFound)
|
|
215
215
|
end
|
|
216
216
|
|
|
@@ -124,6 +124,10 @@ module Capybara
|
|
|
124
124
|
def be_an_invalid_element_error(session)
|
|
125
125
|
satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
|
|
126
126
|
end
|
|
127
|
+
|
|
128
|
+
def with_os_path_separators(path)
|
|
129
|
+
Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
|
|
130
|
+
end
|
|
127
131
|
end
|
|
128
132
|
end
|
|
129
133
|
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<select name="form[locale]" id="form_locale">
|
|
109
109
|
<option value="sv">Swedish</option>
|
|
110
110
|
<option selected="selected" value="en">English</option>
|
|
111
|
-
<option value="fi">
|
|
111
|
+
<option value="fi">Finnish</option>
|
|
112
112
|
<option value="no">Norwegian</option>
|
|
113
113
|
<option value="jo">John's made-up language</option>
|
|
114
114
|
<option value="jbo"> Lojban </option>
|
data/lib/capybara/version.rb
CHANGED
data/lib/capybara/window.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Capybara
|
|
4
4
|
##
|
|
5
|
-
# The Window class represents a browser window.
|
|
5
|
+
# The {Window} class represents a browser window.
|
|
6
6
|
#
|
|
7
7
|
# You can get an instance of the class by calling either of:
|
|
8
8
|
#
|
|
@@ -12,12 +12,12 @@ module Capybara
|
|
|
12
12
|
# * {Capybara::Session#switch_to_window}
|
|
13
13
|
#
|
|
14
14
|
# Note that some drivers (e.g. Selenium) support getting size of/resizing/closing only
|
|
15
|
-
#
|
|
15
|
+
# current window. So if you invoke such method for:
|
|
16
16
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
17
|
+
# * window that is current, Capybara will make 2 Selenium method invocations
|
|
18
|
+
# (get handle of current window + get size/resize/close).
|
|
19
|
+
# * window that is not current, Capybara will make 4 Selenium method invocations
|
|
20
|
+
# (get handle of current window + switch to given handle + get size/resize/close + switch to original handle)
|
|
21
21
|
#
|
|
22
22
|
class Window
|
|
23
23
|
# @return [String] a string that uniquely identifies window within session
|
|
@@ -57,12 +57,12 @@ module Capybara
|
|
|
57
57
|
# Close window.
|
|
58
58
|
#
|
|
59
59
|
# If this method was called for window that is current, then after calling this method
|
|
60
|
-
#
|
|
61
|
-
#
|
|
60
|
+
# future invocations of other Capybara methods should raise
|
|
61
|
+
# {Capybara::Driver::Base#no_such_window_error session.driver.no_such_window_error} until another window will be switched to.
|
|
62
62
|
#
|
|
63
63
|
# @!macro about_current
|
|
64
64
|
# If this method was called for window that is not current, then after calling this method
|
|
65
|
-
# current window
|
|
65
|
+
# current window should remain the same as it was before calling this method.
|
|
66
66
|
#
|
|
67
67
|
def close
|
|
68
68
|
@driver.close_window(handle)
|
|
@@ -93,7 +93,7 @@ module Capybara
|
|
|
93
93
|
# Maximize window.
|
|
94
94
|
#
|
|
95
95
|
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
|
96
|
-
#
|
|
96
|
+
# may not support this method.
|
|
97
97
|
#
|
|
98
98
|
# @macro about_current
|
|
99
99
|
#
|
data/lib/capybara.rb
CHANGED
|
@@ -66,36 +66,44 @@ module Capybara
|
|
|
66
66
|
# config.app_host = 'http://www.google.com'
|
|
67
67
|
# end
|
|
68
68
|
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
69
|
+
# #### Configurable options
|
|
70
|
+
#
|
|
71
|
+
# - **allow_gumbo** (Boolean = `false`) - When `nokogumbo` is available, whether it will be used to parse HTML strings.
|
|
72
|
+
# - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
|
|
73
|
+
# unless another port is explicitly specified.
|
|
74
|
+
# - **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`.
|
|
75
|
+
# - **asset_host** (String = `nil`) - Where dynamic assets are hosted - will be prepended to relative asset locations if present.
|
|
76
|
+
# - **automatic_label_click** (Boolean = `false`) - Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check},
|
|
77
|
+
# {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated `<label>` element if the checkbox/radio button are non-visible.
|
|
78
|
+
# - **automatic_reload** (Boolean = `true`) - Whether to automatically reload elements as Capybara is waiting.
|
|
79
|
+
# - **default_max_wait_time** (Numeric = `2`) - The maximum number of seconds to wait for asynchronous processes to finish.
|
|
80
|
+
# - **default_normalize_ws** (Boolean = `false`) - Whether text predicates and matchers use normalize whitespace behavior.
|
|
81
|
+
# - **default_selector** (`:css`, `:xpath` = `:css`) - Methods which take a selector use the given type by default. See also {Capybara::Selector}.
|
|
82
|
+
# - **default_set_options** (Hash = `{}`) - The default options passed to {Capybara::Node::Element#set Element#set}.
|
|
83
|
+
# - **enable_aria_label** (Boolean = `false`) - Whether fields, links, and buttons will match against `aria-label` attribute.
|
|
84
|
+
# - **exact** (Boolean = `false`) - Whether locators are matched exactly or with substrings. Only affects selector conditions
|
|
85
|
+
# written using the `XPath#is` method.
|
|
86
|
+
# - **exact_text** (Boolean = `false`) - Whether the text matchers and `:text` filter match exactly or on substrings.
|
|
87
|
+
# - **ignore_hidden_elements** (Boolean = `true`) - Whether to ignore hidden elements on the page.
|
|
88
|
+
# - **match** (`:one`, `:first`, `:prefer_exact`, `:smart` = `:smart`) - The matching strategy to find nodes.
|
|
89
|
+
# - **predicates_wait** (Boolean = `true`) - Whether Capybara's predicate matchers use waiting behavior by default.
|
|
90
|
+
# - **raise_server_errors** (Boolean = `true`) - Should errors raised in the server be raised in the tests?
|
|
91
|
+
# - **reuse_server** (Boolean = `true`) - Whether to reuse the server thread between multiple sessions using the same app object.
|
|
92
|
+
# - **run_server** (Boolean = `true`) - Whether to start a Rack server for the given Rack app.
|
|
93
|
+
# - **save_path** (String = `Dir.pwd`) - Where to put pages saved through {Capybara::Session#save_page save_page}, {Capybara::Session#save_screenshot save_screenshot},
|
|
94
|
+
# {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
|
|
95
|
+
# - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
|
|
96
|
+
# - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
|
|
97
|
+
# and {configure raise_server_errors} is `true`.
|
|
98
|
+
# - **test_id** (`Symbol`, `String`, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
|
|
99
|
+
# - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually.
|
|
100
|
+
#
|
|
101
|
+
# #### DSL Options
|
|
102
|
+
#
|
|
103
|
+
# When using `capybara/dsl`, the following options are also available:
|
|
104
|
+
#
|
|
105
|
+
# - **default_driver** (Symbol = `:rack_test`) - The name of the driver to use by default.
|
|
106
|
+
# - **javascript_driver** (Symbol = `:selenium`) - The name of a driver to use for JavaScript enabled tests.
|
|
99
107
|
#
|
|
100
108
|
def configure
|
|
101
109
|
yield config
|
|
@@ -201,15 +209,13 @@ module Capybara
|
|
|
201
209
|
# any string containing HTML in the exact same way you would query the current document in a Capybara
|
|
202
210
|
# session.
|
|
203
211
|
#
|
|
204
|
-
#
|
|
205
|
-
#
|
|
212
|
+
# @example A single element
|
|
206
213
|
# node = Capybara.string('<a href="foo">bar</a>')
|
|
207
214
|
# anchor = node.first('a')
|
|
208
215
|
# anchor[:href] #=> 'foo'
|
|
209
216
|
# anchor.text #=> 'bar'
|
|
210
217
|
#
|
|
211
|
-
#
|
|
212
|
-
#
|
|
218
|
+
# @example Multiple elements
|
|
213
219
|
# node = Capybara.string <<-HTML
|
|
214
220
|
# <ul>
|
|
215
221
|
# <li id="home">Home</li>
|
|
@@ -297,7 +303,7 @@ module Capybara
|
|
|
297
303
|
|
|
298
304
|
##
|
|
299
305
|
#
|
|
300
|
-
# The current Capybara::Session based on what is set as
|
|
306
|
+
# The current {Capybara::Session} based on what is set as {app} and {current_driver}.
|
|
301
307
|
#
|
|
302
308
|
# @return [Capybara::Session] The currently used session
|
|
303
309
|
#
|
|
@@ -340,7 +346,7 @@ module Capybara
|
|
|
340
346
|
|
|
341
347
|
##
|
|
342
348
|
#
|
|
343
|
-
# Yield a block using a specific session name or Capybara::Session instance.
|
|
349
|
+
# Yield a block using a specific session name or {Capybara::Session} instance.
|
|
344
350
|
#
|
|
345
351
|
def using_session(name_or_session)
|
|
346
352
|
previous_session_info = {
|
data/spec/minitest_spec.rb
CHANGED
|
@@ -130,6 +130,16 @@ class MinitestTest < Minitest::Test
|
|
|
130
130
|
visit('/with_html')
|
|
131
131
|
assert_matches_style(find(:css, '#second'), display: 'inline')
|
|
132
132
|
end
|
|
133
|
+
|
|
134
|
+
def test_assert_ancestor
|
|
135
|
+
option = find(:option, 'Finnish')
|
|
136
|
+
assert_ancestor(option, :css, '#form_locale')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_assert_sibling
|
|
140
|
+
option = find(:css, '#form_title').find(:option, 'Mrs')
|
|
141
|
+
assert_sibling(option, :option, 'Mr')
|
|
142
|
+
end
|
|
133
143
|
end
|
|
134
144
|
|
|
135
145
|
RSpec.describe 'capybara/minitest' do
|
|
@@ -148,6 +158,6 @@ RSpec.describe 'capybara/minitest' do
|
|
|
148
158
|
reporter.start
|
|
149
159
|
MinitestTest.run reporter, {}
|
|
150
160
|
reporter.report
|
|
151
|
-
expect(output.string).to include('
|
|
161
|
+
expect(output.string).to include('22 runs, 52 assertions, 0 failures, 0 errors, 1 skips')
|
|
152
162
|
end
|
|
153
163
|
end
|
data/spec/minitest_spec_spec.rb
CHANGED
|
@@ -127,6 +127,16 @@ class MinitestSpecTest < Minitest::Spec
|
|
|
127
127
|
find(:css, '#second').must_have_style('display' => 'inline') # deprecated
|
|
128
128
|
find(:css, '#second').must_match_style('display' => 'inline')
|
|
129
129
|
end
|
|
130
|
+
|
|
131
|
+
it 'supports ancestor expectations' do
|
|
132
|
+
option = find(:option, 'Finnish')
|
|
133
|
+
option.must_have_ancestor(:css, '#form_locale')
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'supports sibling expectations' do
|
|
137
|
+
option = find(:css, '#form_title').find(:option, 'Mrs')
|
|
138
|
+
option.must_have_sibling(:option, 'Mr')
|
|
139
|
+
end
|
|
130
140
|
end
|
|
131
141
|
|
|
132
142
|
RSpec.describe 'capybara/minitest/spec' do
|
|
@@ -145,7 +155,7 @@ RSpec.describe 'capybara/minitest/spec' do
|
|
|
145
155
|
reporter.start
|
|
146
156
|
MinitestSpecTest.run reporter, {}
|
|
147
157
|
reporter.report
|
|
148
|
-
expect(output.string).to include('
|
|
158
|
+
expect(output.string).to include('22 runs, 44 assertions, 1 failures, 0 errors, 1 skips')
|
|
149
159
|
# Make sure error messages are displayed
|
|
150
160
|
expect(output.string).to match(/expected to find select box "non_existing_form_title" .*but there were no matches/)
|
|
151
161
|
end
|
|
@@ -64,6 +64,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
|
|
|
64
64
|
pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
|
|
65
65
|
when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
|
|
66
66
|
pending "Geckodriver doesn't allow clicking on file inputs"
|
|
67
|
+
when /drag_to.*HTML5/
|
|
68
|
+
pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
|
|
67
69
|
end
|
|
68
70
|
end
|
|
69
71
|
|
data/spec/selenium_spec_ie.rb
CHANGED
|
@@ -6,13 +6,13 @@ require 'shared_selenium_session'
|
|
|
6
6
|
require 'shared_selenium_node'
|
|
7
7
|
require 'rspec/shared_spec_matchers'
|
|
8
8
|
|
|
9
|
-
if ENV['CI']
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
9
|
+
# if ENV['CI']
|
|
10
|
+
# if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
|
11
|
+
# ::Selenium::WebDriver::IE::Service
|
|
12
|
+
# else
|
|
13
|
+
# ::Selenium::WebDriver::IE
|
|
14
|
+
# end.driver_path = 'C:\Tools\WebDriver\IEDriverServer.exe'
|
|
15
|
+
# end
|
|
16
16
|
|
|
17
17
|
def selenium_host
|
|
18
18
|
ENV.fetch('SELENIUM_HOST', '192.168.56.102')
|
|
@@ -110,6 +110,12 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
|
|
|
110
110
|
pending 'IE treats blank href as a parent request (against HTML spec)'
|
|
111
111
|
when /#attach_file with a block/
|
|
112
112
|
skip 'Hangs IE testing for unknown reason'
|
|
113
|
+
when /drag_to.*HTML5/
|
|
114
|
+
pending "IE doesn't support a DataTransfer constuctor"
|
|
115
|
+
when /template elements should not be visible/
|
|
116
|
+
skip "IE doesn't support template elements"
|
|
117
|
+
when /Element#drop/
|
|
118
|
+
pending "IE doesn't support DataTransfer constructor"
|
|
113
119
|
end
|
|
114
120
|
end
|
|
115
121
|
|
|
@@ -73,6 +73,8 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
|
|
|
73
73
|
when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
|
|
74
74
|
'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
|
|
75
75
|
skip 'safaridriver loses the ability to find elements in the document after `go_back`'
|
|
76
|
+
when /drag_to.*HTML5/
|
|
77
|
+
pending "Safari doesn't support"
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
|
|
@@ -303,57 +303,6 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
|
303
303
|
end
|
|
304
304
|
end
|
|
305
305
|
|
|
306
|
-
describe 'Element#drag_to' do
|
|
307
|
-
before do
|
|
308
|
-
skip "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, session)
|
|
309
|
-
skip "IE doesn't support a DataTransfer constuctor" if ie?(session)
|
|
310
|
-
skip "Safari doesn't support" if safari?(session)
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
it 'should HTML5 drag and drop an object' do
|
|
314
|
-
session.visit('/with_js')
|
|
315
|
-
element = session.find('//div[@id="drag_html5"]')
|
|
316
|
-
target = session.find('//div[@id="drop_html5"]')
|
|
317
|
-
element.drag_to(target)
|
|
318
|
-
expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
it 'should set clientX/Y in dragover events' do
|
|
322
|
-
session.visit('/with_js')
|
|
323
|
-
element = session.find('//div[@id="drag_html5"]')
|
|
324
|
-
target = session.find('//div[@id="drop_html5"]')
|
|
325
|
-
element.drag_to(target)
|
|
326
|
-
session.all(:css, 'div.log').each { |el| puts el.text }
|
|
327
|
-
expect(session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
it 'should not HTML5 drag and drop on a non HTML5 drop element' do
|
|
331
|
-
session.visit('/with_js')
|
|
332
|
-
element = session.find('//div[@id="drag_html5"]')
|
|
333
|
-
target = session.find('//div[@id="drop_html5"]')
|
|
334
|
-
target.execute_script("$(this).removeClass('drop');")
|
|
335
|
-
element.drag_to(target)
|
|
336
|
-
sleep 1
|
|
337
|
-
expect(session).not_to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
it 'should HTML5 drag and drop when scrolling needed' do
|
|
341
|
-
session.visit('/with_js')
|
|
342
|
-
element = session.find('//div[@id="drag_html5_scroll"]')
|
|
343
|
-
target = session.find('//div[@id="drop_html5_scroll"]')
|
|
344
|
-
element.drag_to(target)
|
|
345
|
-
expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5_scroll")]')
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
it 'should drag HTML5 default draggable elements' do
|
|
349
|
-
session.visit('/with_js')
|
|
350
|
-
link = session.find_link('drag_link_html5')
|
|
351
|
-
target = session.find(:id, 'drop_html5')
|
|
352
|
-
link.drag_to target
|
|
353
|
-
expect(session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
|
354
|
-
end
|
|
355
|
-
end
|
|
356
|
-
|
|
357
306
|
describe 'Capybara#Node#attach_file' do
|
|
358
307
|
it 'can attach a directory' do
|
|
359
308
|
pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
|
|
@@ -472,6 +421,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
|
472
421
|
describe 'with react' do
|
|
473
422
|
context 'controlled components' do
|
|
474
423
|
it 'can set and clear a text field' do
|
|
424
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
475
425
|
# session.visit 'https://reactjs.org/docs/forms.html'
|
|
476
426
|
# session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
|
|
477
427
|
# copied into local view
|
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.22.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: 2019-05-
|
|
13
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: addressable
|
|
@@ -88,14 +88,14 @@ dependencies:
|
|
|
88
88
|
requirements:
|
|
89
89
|
- - "~>"
|
|
90
90
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: '1.
|
|
91
|
+
version: '1.5'
|
|
92
92
|
type: :runtime
|
|
93
93
|
prerelease: false
|
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
|
96
96
|
- - "~>"
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: '1.
|
|
98
|
+
version: '1.5'
|
|
99
99
|
- !ruby/object:Gem::Dependency
|
|
100
100
|
name: xpath
|
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -413,6 +413,7 @@ executables: []
|
|
|
413
413
|
extensions: []
|
|
414
414
|
extra_rdoc_files: []
|
|
415
415
|
files:
|
|
416
|
+
- ".yardopts"
|
|
416
417
|
- History.md
|
|
417
418
|
- License.txt
|
|
418
419
|
- README.md
|
|
@@ -460,8 +461,10 @@ files:
|
|
|
460
461
|
- lib/capybara/rspec/matchers/become_closed.rb
|
|
461
462
|
- lib/capybara/rspec/matchers/compound.rb
|
|
462
463
|
- lib/capybara/rspec/matchers/count_sugar.rb
|
|
464
|
+
- lib/capybara/rspec/matchers/have_ancestor.rb
|
|
463
465
|
- lib/capybara/rspec/matchers/have_current_path.rb
|
|
464
466
|
- lib/capybara/rspec/matchers/have_selector.rb
|
|
467
|
+
- lib/capybara/rspec/matchers/have_sibling.rb
|
|
465
468
|
- lib/capybara/rspec/matchers/have_text.rb
|
|
466
469
|
- lib/capybara/rspec/matchers/have_title.rb
|
|
467
470
|
- lib/capybara/rspec/matchers/match_selector.rb
|
|
@@ -579,6 +582,7 @@ files:
|
|
|
579
582
|
- lib/capybara/spec/session/go_back_spec.rb
|
|
580
583
|
- lib/capybara/spec/session/go_forward_spec.rb
|
|
581
584
|
- lib/capybara/spec/session/has_all_selectors_spec.rb
|
|
585
|
+
- lib/capybara/spec/session/has_ancestor_spec.rb
|
|
582
586
|
- lib/capybara/spec/session/has_any_selectors_spec.rb
|
|
583
587
|
- lib/capybara/spec/session/has_button_spec.rb
|
|
584
588
|
- lib/capybara/spec/session/has_css_spec.rb
|
|
@@ -588,6 +592,7 @@ files:
|
|
|
588
592
|
- lib/capybara/spec/session/has_none_selectors_spec.rb
|
|
589
593
|
- lib/capybara/spec/session/has_select_spec.rb
|
|
590
594
|
- lib/capybara/spec/session/has_selector_spec.rb
|
|
595
|
+
- lib/capybara/spec/session/has_sibling_spec.rb
|
|
591
596
|
- lib/capybara/spec/session/has_table_spec.rb
|
|
592
597
|
- lib/capybara/spec/session/has_text_spec.rb
|
|
593
598
|
- lib/capybara/spec/session/has_title_spec.rb
|