capybara 3.35.0 → 3.40.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 +168 -5
- data/README.md +199 -39
- data/lib/capybara/config.rb +16 -4
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/driver/node.rb +5 -1
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/helpers.rb +9 -14
- data/lib/capybara/minitest/spec.rb +18 -6
- data/lib/capybara/minitest.rb +14 -1
- data/lib/capybara/node/actions.rb +14 -9
- data/lib/capybara/node/base.rb +2 -1
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/element.rb +13 -2
- data/lib/capybara/node/finders.rb +11 -2
- data/lib/capybara/node/matchers.rb +25 -0
- data/lib/capybara/node/simple.rb +5 -1
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +2 -1
- data/lib/capybara/queries/base_query.rb +2 -2
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +40 -11
- data/lib/capybara/queries/sibling_query.rb +2 -1
- data/lib/capybara/queries/text_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +64 -8
- data/lib/capybara/rack_test/driver.rb +4 -4
- data/lib/capybara/rack_test/form.rb +29 -7
- data/lib/capybara/rack_test/node.rb +32 -33
- data/lib/capybara/registration_container.rb +2 -5
- data/lib/capybara/registrations/drivers.rb +7 -7
- data/lib/capybara/registrations/servers.rb +37 -16
- data/lib/capybara/result.rb +2 -2
- data/lib/capybara/rspec/matcher_proxies.rb +6 -6
- data/lib/capybara/rspec/matchers/base.rb +8 -6
- data/lib/capybara/rspec/matchers/compound.rb +1 -1
- data/lib/capybara/rspec/matchers/have_selector.rb +9 -17
- data/lib/capybara/rspec/matchers.rb +21 -16
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
- data/lib/capybara/selector/css.rb +6 -6
- data/lib/capybara/selector/definition/button.rb +10 -5
- data/lib/capybara/selector/definition/checkbox.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/link.rb +2 -1
- data/lib/capybara/selector/definition/radio_button.rb +1 -1
- data/lib/capybara/selector/definition/table.rb +1 -1
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/definition.rb +4 -2
- data/lib/capybara/selector/filter_set.rb +4 -7
- data/lib/capybara/selector/regexp_disassembler.rb +2 -5
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selector.rb +252 -0
- data/lib/capybara/selenium/driver.rb +31 -54
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +9 -5
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -7
- data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
- data/lib/capybara/selenium/node.rb +60 -38
- data/lib/capybara/selenium/nodes/chrome_node.rb +4 -16
- data/lib/capybara/selenium/nodes/edge_node.rb +19 -13
- data/lib/capybara/selenium/nodes/firefox_node.rb +3 -3
- data/lib/capybara/selenium/nodes/safari_node.rb +4 -4
- data/lib/capybara/selenium/patches/atoms.rb +1 -1
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
- data/lib/capybara/server/animation_disabler.rb +40 -23
- data/lib/capybara/server/middleware.rb +1 -1
- data/lib/capybara/server.rb +1 -1
- data/lib/capybara/session/config.rb +4 -2
- data/lib/capybara/session.rb +34 -34
- data/lib/capybara/spec/public/test.js +4 -0
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +11 -15
- data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
- data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
- data/lib/capybara/spec/session/check_spec.rb +10 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_spec.rb +12 -1
- data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
- data/lib/capybara/spec/session/find_link_spec.rb +10 -0
- data/lib/capybara/spec/session/find_spec.rb +15 -1
- data/lib/capybara/spec/session/first_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
- data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -2
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
- data/lib/capybara/spec/session/has_button_spec.rb +30 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +3 -3
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +25 -1
- data/lib/capybara/spec/session/has_link_spec.rb +40 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
- data/lib/capybara/spec/session/has_select_spec.rb +10 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
- data/lib/capybara/spec/session/has_table_spec.rb +13 -2
- data/lib/capybara/spec/session/has_text_spec.rb +6 -14
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
- data/lib/capybara/spec/session/node_spec.rb +88 -1
- data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +13 -0
- data/lib/capybara/spec/session/scroll_spec.rb +7 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +1 -1
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- data/lib/capybara/spec/session/window/window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
- data/lib/capybara/spec/session/within_spec.rb +13 -0
- data/lib/capybara/spec/spec_helper.rb +12 -5
- data/lib/capybara/spec/test_app.rb +91 -14
- data/lib/capybara/spec/views/animated.erb +1 -1
- data/lib/capybara/spec/views/form.erb +34 -4
- data/lib/capybara/spec/views/frame_child.erb +1 -1
- data/lib/capybara/spec/views/frame_one.erb +1 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +1 -1
- data/lib/capybara/spec/views/offset.erb +2 -1
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +2 -2
- data/lib/capybara/spec/views/scroll.erb +2 -1
- data/lib/capybara/spec/views/spatial.erb +1 -1
- data/lib/capybara/spec/views/with_animation.erb +2 -3
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +2 -2
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +2 -2
- data/lib/capybara/spec/views/with_html.erb +5 -3
- data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
- data/lib/capybara/spec/views/with_js.erb +2 -3
- data/lib/capybara/spec/views/with_jstree.erb +1 -1
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +30 -30
- data/spec/basic_node_spec.rb +16 -3
- data/spec/capybara_spec.rb +12 -0
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +1 -1
- data/spec/css_splitter_spec.rb +1 -1
- data/spec/dsl_spec.rb +5 -3
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
- data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
- data/spec/minitest_spec.rb +12 -1
- data/spec/minitest_spec_spec.rb +4 -0
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +30 -12
- data/spec/result_spec.rb +41 -35
- data/spec/rspec/features_spec.rb +3 -3
- data/spec/rspec/scenarios_spec.rb +2 -2
- data/spec/rspec/shared_spec_matchers.rb +27 -3
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +3 -3
- data/spec/sauce_spec_chrome.rb +5 -5
- data/spec/selector_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +20 -18
- data/spec/selenium_spec_chrome_remote.rb +15 -19
- data/spec/selenium_spec_edge.rb +19 -6
- data/spec/selenium_spec_firefox.rb +26 -8
- data/spec/selenium_spec_firefox_remote.rb +18 -4
- data/spec/selenium_spec_ie.rb +7 -8
- data/spec/selenium_spec_safari.rb +34 -20
- data/spec/server_spec.rb +19 -7
- data/spec/shared_selenium_node.rb +0 -4
- data/spec/shared_selenium_session.rb +22 -14
- data/spec/spec_helper.rb +36 -3
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +1 -1
- metadata +49 -30
- data/lib/capybara/selenium/logger_suppressor.rb +0 -34
- data/lib/capybara/selenium/patches/action_pauser.rb +0 -26
- data/lib/capybara/spec/views/with_title.erb +0 -5
data/spec/result_spec.rb
CHANGED
@@ -30,6 +30,15 @@ RSpec.describe Capybara::Result do
|
|
30
30
|
result.last.text == 'Delta'
|
31
31
|
end
|
32
32
|
|
33
|
+
it 'splats into multiple assignment' do
|
34
|
+
first, *rest, last = result
|
35
|
+
|
36
|
+
expect(first).to have_text 'Alpha'
|
37
|
+
expect(rest.first).to have_text 'Beta'
|
38
|
+
expect(rest.last).to have_text 'Gamma'
|
39
|
+
expect(last).to have_text 'Delta'
|
40
|
+
end
|
41
|
+
|
33
42
|
it 'can supports values_at method' do
|
34
43
|
expect(result.values_at(0, 2).map(&:text)).to eq(%w[Alpha Gamma])
|
35
44
|
end
|
@@ -78,34 +87,31 @@ RSpec.describe Capybara::Result do
|
|
78
87
|
expect(recalc_result[1...3].map(&:text)).to eq %w[Beta Gamma]
|
79
88
|
expect(recalc_result[1..7].map(&:text)).to eq %w[Beta Gamma Delta]
|
80
89
|
expect(recalc_result[2...-1].map(&:text)).to eq %w[Gamma]
|
81
|
-
expect(recalc_result[2..-1].map(&:text)).to eq %w[Gamma Delta]
|
90
|
+
expect(recalc_result[2..-1].map(&:text)).to eq %w[Gamma Delta] # rubocop:disable Style/SlicingWithRange
|
91
|
+
expect(recalc_result[2..].map(&:text)).to eq %w[Gamma Delta]
|
82
92
|
end
|
83
93
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
TEST
|
94
|
+
it 'supports endless ranges' do
|
95
|
+
expect(result[2..].map(&:text)).to eq %w[Gamma Delta]
|
96
|
+
end
|
89
97
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
98
|
+
it 'supports inclusive positive beginless ranges' do
|
99
|
+
expect(result[..2].map(&:text)).to eq %w[Alpha Beta Gamma]
|
100
|
+
end
|
94
101
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
102
|
+
it 'supports inclusive negative beginless ranges' do
|
103
|
+
expect(result[..-2].map(&:text)).to eq %w[Alpha Beta Gamma]
|
104
|
+
expect(result[..-1].map(&:text)).to eq %w[Alpha Beta Gamma Delta]
|
105
|
+
end
|
99
106
|
|
100
|
-
|
101
|
-
|
102
|
-
|
107
|
+
it 'supports exclusive positive beginless ranges' do
|
108
|
+
expect(result[...2].map(&:text)).to eq %w[Alpha Beta]
|
109
|
+
end
|
103
110
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
TEST
|
111
|
+
it 'supports exclusive negative beginless ranges' do
|
112
|
+
expect(result[...-2].map(&:text)).to eq %w[Alpha Beta]
|
113
|
+
expect(result[...-1].map(&:text)).to eq %w[Alpha Beta Gamma]
|
114
|
+
end
|
109
115
|
|
110
116
|
it 'works with filter blocks' do
|
111
117
|
result = string.all('//li') { |node| node.text == 'Alpha' }
|
@@ -116,52 +122,52 @@ RSpec.describe Capybara::Result do
|
|
116
122
|
it 'should evaluate filters lazily for idx' do
|
117
123
|
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
|
118
124
|
# Not processed until accessed
|
119
|
-
expect(result.instance_variable_get(
|
125
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 0
|
120
126
|
|
121
127
|
# Only one retrieved when needed
|
122
128
|
result.first
|
123
|
-
expect(result.instance_variable_get(
|
129
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 1
|
124
130
|
|
125
131
|
# works for indexed access
|
126
132
|
result[0]
|
127
|
-
expect(result.instance_variable_get(
|
133
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 1
|
128
134
|
|
129
135
|
result[2]
|
130
|
-
expect(result.instance_variable_get(
|
136
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 3
|
131
137
|
|
132
138
|
# All cached when converted to array
|
133
139
|
result.to_a
|
134
|
-
expect(result.instance_variable_get(
|
140
|
+
expect(result.instance_variable_get(:@result_cache).size).to eq 4
|
135
141
|
end
|
136
142
|
|
137
143
|
it 'should evaluate filters lazily for range' do
|
138
144
|
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
|
139
145
|
result[0..1]
|
140
|
-
expect(result.instance_variable_get(
|
146
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 2
|
141
147
|
|
142
148
|
expect(result[0..7].size).to eq 4
|
143
|
-
expect(result.instance_variable_get(
|
149
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 4
|
144
150
|
end
|
145
151
|
|
146
152
|
it 'should evaluate filters lazily for idx and length' do
|
147
153
|
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
|
148
154
|
result[1, 2]
|
149
|
-
expect(result.instance_variable_get(
|
155
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 3
|
150
156
|
|
151
157
|
expect(result[2, 5].size).to eq 2
|
152
|
-
expect(result.instance_variable_get(
|
158
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 4
|
153
159
|
end
|
154
160
|
|
155
161
|
it 'should only need to evaluate one result for any?' do
|
156
162
|
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
|
157
163
|
result.any?
|
158
|
-
expect(result.instance_variable_get(
|
164
|
+
expect(result.instance_variable_get(:@result_cache).size).to be 1
|
159
165
|
end
|
160
166
|
|
161
167
|
it 'should evaluate all elements when #to_a called' do
|
162
168
|
# All cached when converted to array
|
163
169
|
result.to_a
|
164
|
-
expect(result.instance_variable_get(
|
170
|
+
expect(result.instance_variable_get(:@result_cache).size).to eq 4
|
165
171
|
end
|
166
172
|
|
167
173
|
describe '#each' do
|
@@ -170,7 +176,7 @@ RSpec.describe Capybara::Result do
|
|
170
176
|
results = []
|
171
177
|
result.each do |el|
|
172
178
|
results << el
|
173
|
-
expect(result.instance_variable_get(
|
179
|
+
expect(result.instance_variable_get(:@result_cache).size).to eq results.size
|
174
180
|
end
|
175
181
|
|
176
182
|
expect(results.size).to eq 4
|
@@ -184,7 +190,7 @@ RSpec.describe Capybara::Result do
|
|
184
190
|
it 'lazily evaluates' do
|
185
191
|
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
|
186
192
|
result.each.with_index do |_el, idx|
|
187
|
-
expect(result.instance_variable_get(
|
193
|
+
expect(result.instance_variable_get(:@result_cache).size).to eq(idx + 1) # 0 indexing
|
188
194
|
end
|
189
195
|
end
|
190
196
|
end
|
data/spec/rspec/features_spec.rb
CHANGED
@@ -91,11 +91,11 @@ end
|
|
91
91
|
|
92
92
|
ffeature 'if ffeature aliases focused tag then' do # rubocop:disable RSpec/Focus
|
93
93
|
scenario 'scenario inside this feature has metatag focus tag' do |example|
|
94
|
-
expect(example.metadata[:focus]).to
|
94
|
+
expect(example.metadata[:focus]).to be true
|
95
95
|
end
|
96
96
|
|
97
|
-
scenario 'other scenarios also has metatag focus tag
|
98
|
-
expect(example.metadata[:focus]).to
|
97
|
+
scenario 'other scenarios also has metatag focus tag' do |example|
|
98
|
+
expect(example.metadata[:focus]).to be true
|
99
99
|
end
|
100
100
|
end
|
101
101
|
# rubocop:enable RSpec/RepeatedExample, RSpec/MultipleDescribes
|
@@ -11,12 +11,12 @@ end
|
|
11
11
|
|
12
12
|
feature 'if fscenario aliases focused tag then' do
|
13
13
|
fscenario 'scenario should have focused meta tag' do |example| # rubocop:disable RSpec/Focus
|
14
|
-
expect(example.metadata[:focus]).to
|
14
|
+
expect(example.metadata[:focus]).to be true
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
feature 'if xscenario aliases to pending then' do
|
19
|
-
xscenario "this test should be 'temporarily disabled with xscenario'" do
|
19
|
+
xscenario "this test should be 'temporarily disabled with xscenario'" do # rubocop:disable RSpec/PendingWithoutReason
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -120,7 +120,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
120
120
|
|
121
121
|
describe 'have_xpath matcher' do
|
122
122
|
it 'gives proper description' do
|
123
|
-
expect(have_xpath('//h1').description).to eq(
|
123
|
+
expect(have_xpath('//h1').description).to eq('have visible xpath "//h1"')
|
124
124
|
end
|
125
125
|
|
126
126
|
context 'on a string' do
|
@@ -503,6 +503,30 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
503
503
|
end
|
504
504
|
end
|
505
505
|
|
506
|
+
describe 'have_element matcher' do
|
507
|
+
let(:html) { '<img src="/img.jpg" alt="a JPEG"><img src="/img.png" alt="a PNG">' }
|
508
|
+
|
509
|
+
it 'gives proper description' do
|
510
|
+
expect(have_element('img').description).to eq('have visible element "img"')
|
511
|
+
end
|
512
|
+
|
513
|
+
it 'passes if there is such a element' do
|
514
|
+
expect(html).to have_element('img', src: '/img.jpg')
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'fails if there is no such element' do
|
518
|
+
expect do
|
519
|
+
expect(html).to have_element('photo')
|
520
|
+
end.to raise_error(/expected to find element "photo"/)
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'supports compounding' do
|
524
|
+
expect(html).to have_element('img', alt: 'a JPEG').and have_element('img', src: '/img.png')
|
525
|
+
expect(html).to have_element('photo').or have_element('img', src: '/img.jpg')
|
526
|
+
expect(html).to have_no_element('photo').and have_element('img', alt: 'a PNG')
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
506
530
|
describe 'have_link matcher' do
|
507
531
|
let(:html) { '<a href="#">Just a link</a><a href="#">Another link</a>' }
|
508
532
|
|
@@ -840,10 +864,10 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
840
864
|
end
|
841
865
|
|
842
866
|
it 'gives proper description when :visible option passed' do
|
843
|
-
expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"')
|
867
|
+
expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
844
868
|
expect(have_table('Lovely table', visible: :hidden).description).to eq('have non-visible table "Lovely table"')
|
845
869
|
expect(have_table('Lovely table', visible: :all).description).to eq('have table "Lovely table"')
|
846
|
-
expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"')
|
870
|
+
expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
847
871
|
end
|
848
872
|
|
849
873
|
it 'passes if there is such a table' do
|
data/spec/rspec_matchers_spec.rb
CHANGED
@@ -56,6 +56,31 @@ RSpec.describe 'Capybara RSpec Matchers', type: :feature do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
context 'with a filter block' do
|
60
|
+
it 'applies the filter' do
|
61
|
+
visit('/with_html')
|
62
|
+
expect(page).to have_selector(:css, 'input#test_field')
|
63
|
+
|
64
|
+
expect(page).to have_selector(:css, 'input', count: 1) { |input| input.value == 'monkey' }
|
65
|
+
expect(page).to have_selector(:css, 'input', count: 1) do |input|
|
66
|
+
input.value == 'monkey'
|
67
|
+
end
|
68
|
+
expect(page).to have_no_selector(:css, 'input#test_field') { |input| input.value == 'not a monkey' }
|
69
|
+
expect(page).to have_no_selector(:css, 'input#test_field') do |input|
|
70
|
+
input.value == 'not a monkey'
|
71
|
+
end
|
72
|
+
|
73
|
+
expect(page).not_to have_selector(:css, 'input#test_field') { |input| input.value == 'not a monkey' }
|
74
|
+
expect(page).not_to have_selector(:css, 'input#test_field') do |input|
|
75
|
+
input.value == 'not a monkey'
|
76
|
+
end
|
77
|
+
expect(page).not_to have_no_selector(:css, 'input', count: 1) { |input| input.value == 'monkey' }
|
78
|
+
expect(page).not_to have_no_selector(:css, 'input#test_field', count: 1) do |input|
|
79
|
+
input.value == 'monkey'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
59
84
|
def error_msg_for(&block)
|
60
85
|
expect(&block).to(raise_error { |e| return e.message })
|
61
86
|
end
|
data/spec/rspec_spec.rb
CHANGED
@@ -15,7 +15,7 @@ RSpec.describe 'capybara/rspec' do
|
|
15
15
|
expect(self.class.ancestors).to include Capybara::RSpecMatcherProxies
|
16
16
|
end
|
17
17
|
|
18
|
-
context 'resetting session' do
|
18
|
+
context 'resetting session', order: :defined do
|
19
19
|
it 'sets a cookie in one example...' do
|
20
20
|
visit('/set_cookie')
|
21
21
|
expect(page.body).to include('Cookie set to test_cookie')
|
@@ -27,7 +27,7 @@ RSpec.describe 'capybara/rspec' do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
context 'setting the current driver' do
|
30
|
+
context 'setting the current driver', order: :defined do
|
31
31
|
it 'sets the current driver in one example...' do
|
32
32
|
Capybara.current_driver = :selenium
|
33
33
|
end
|
@@ -37,7 +37,7 @@ RSpec.describe 'capybara/rspec' do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
it 'switches to the javascript driver when giving it as metadata', js
|
40
|
+
it 'switches to the javascript driver when giving it as metadata', :js do
|
41
41
|
expect(Capybara.current_driver).to eq(Capybara.javascript_driver)
|
42
42
|
end
|
43
43
|
|
data/spec/sauce_spec_chrome.rb
CHANGED
@@ -10,14 +10,14 @@ require 'sauce_whisk'
|
|
10
10
|
|
11
11
|
Capybara.register_driver :sauce_chrome do |app|
|
12
12
|
options = {
|
13
|
-
selenium_version: '
|
13
|
+
selenium_version: '4.8.0',
|
14
14
|
platform: 'macOS 10.12',
|
15
15
|
browser_name: 'chrome',
|
16
16
|
version: '65.0',
|
17
17
|
name: 'Capybara test',
|
18
|
-
build: ENV
|
19
|
-
username: ENV
|
20
|
-
access_key: ENV
|
18
|
+
build: ENV.fetch('TRAVIS_REPO_SLUG', "Ruby-RSpec-Selenium: Local-#{Time.now.to_i}"),
|
19
|
+
username: ENV.fetch('SAUCE_USERNAME', nil),
|
20
|
+
access_key: ENV.fetch('SAUCE_ACCESS_KEY', nil)
|
21
21
|
}
|
22
22
|
|
23
23
|
options.delete(:browser_name)
|
@@ -27,7 +27,7 @@ Capybara.register_driver :sauce_chrome do |app|
|
|
27
27
|
|
28
28
|
Capybara::Selenium::Driver.new(app,
|
29
29
|
browser: :remote, url: url,
|
30
|
-
|
30
|
+
capabilities: capabilities,
|
31
31
|
options: Selenium::WebDriver::Chrome::Options.new(args: ['']))
|
32
32
|
end
|
33
33
|
|
data/spec/selector_spec.rb
CHANGED
@@ -111,13 +111,13 @@ RSpec.describe Capybara do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
describe 'adding a selector' do
|
114
|
-
it 'can set default
|
114
|
+
it 'can set default visibility' do
|
115
115
|
described_class.add_selector :hidden_field do
|
116
116
|
visible :hidden
|
117
117
|
css { |_sel| 'input[type="hidden"]' }
|
118
118
|
end
|
119
119
|
|
120
|
-
expect(string).to have_no_css('input[type="hidden"]')
|
120
|
+
expect(string).to have_no_css('input[type="hidden"]') # rubocop:disable Capybara/SpecificMatcher
|
121
121
|
expect(string).to have_selector(:hidden_field)
|
122
122
|
end
|
123
123
|
end
|
@@ -159,7 +159,7 @@ RSpec.describe Capybara do
|
|
159
159
|
end
|
160
160
|
|
161
161
|
it 'returns nil if no match' do
|
162
|
-
expect(Capybara::Selector.for('nothing')).to
|
162
|
+
expect(Capybara::Selector.for('nothing')).to be_nil
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
@@ -471,7 +471,7 @@ RSpec.describe Capybara do
|
|
471
471
|
end
|
472
472
|
|
473
473
|
it 'includes wildcarded keys in description' do
|
474
|
-
expect { string.
|
474
|
+
expect { string.all(:element, 'input', not_there: 'bad', presence: true, absence: false, count: 1) }
|
475
475
|
.to(raise_error do |e|
|
476
476
|
expect(e).to be_a(Capybara::ElementNotFound)
|
477
477
|
expect(e.message).to include 'not_there => bad'
|
@@ -8,11 +8,16 @@ require 'rspec/shared_spec_matchers'
|
|
8
8
|
|
9
9
|
CHROME_DRIVER = :selenium_chrome
|
10
10
|
|
11
|
-
Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV
|
11
|
+
Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV.fetch('CI', nil) && ENV.fetch('CHROME_BETA', nil)
|
12
|
+
|
13
|
+
Selenium::WebDriver.logger.ignore(:selenium_manager)
|
14
|
+
|
15
|
+
browser_options = if ENV['HEADLESS']
|
16
|
+
Selenium::WebDriver::Options.chrome(args: ['--headless=new'])
|
17
|
+
else
|
18
|
+
Selenium::WebDriver::Options.chrome
|
19
|
+
end
|
12
20
|
|
13
|
-
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
14
|
-
browser_options.headless! if ENV['HEADLESS']
|
15
|
-
browser_options.add_option(:w3c, ENV['W3C'] != 'false')
|
16
21
|
# Chromedriver 77 requires setting this for headless mode on linux
|
17
22
|
# Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
|
18
23
|
browser_options.add_preference('download.default_directory', Capybara.save_path)
|
@@ -83,12 +88,10 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
|
|
83
88
|
case example.metadata[:full_description]
|
84
89
|
when /#click_link can download a file$/
|
85
90
|
skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
|
86
|
-
when /Capybara::Session selenium_chrome
|
87
|
-
pending "
|
88
|
-
when /Capybara::
|
89
|
-
skip '
|
90
|
-
when /node #right_click delay should delay the mouse up/
|
91
|
-
skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
|
91
|
+
when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
|
92
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
93
|
+
when /Capybara::Session selenium_chrome node #shadow_root/
|
94
|
+
skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
|
92
95
|
end
|
93
96
|
end
|
94
97
|
|
@@ -185,23 +188,22 @@ RSpec.describe 'Capybara::Session with chrome' do
|
|
185
188
|
end
|
186
189
|
|
187
190
|
describe 'log access' do
|
188
|
-
|
191
|
+
let(:logs) do
|
192
|
+
session.driver.browser.then do |chrome_driver|
|
193
|
+
chrome_driver.respond_to?(:logs) ? chrome_driver : chrome_driver.manage
|
194
|
+
end.logs
|
195
|
+
end
|
189
196
|
|
190
197
|
it 'does not error getting log types' do
|
191
|
-
skip if Gem::Requirement.new('< 75.0.3770.90').satisfied_by? chromedriver_version
|
192
198
|
expect do
|
193
|
-
|
199
|
+
logs.available_types
|
194
200
|
end.not_to raise_error
|
195
201
|
end
|
196
202
|
|
197
203
|
it 'does not error when getting logs' do
|
198
204
|
expect do
|
199
|
-
|
205
|
+
logs.get(:browser)
|
200
206
|
end.not_to raise_error
|
201
207
|
end
|
202
208
|
end
|
203
|
-
|
204
|
-
def chromedriver_version
|
205
|
-
Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
|
206
|
-
end
|
207
209
|
end
|
@@ -21,8 +21,8 @@ def ensure_selenium_running!
|
|
21
21
|
rescue StandardError
|
22
22
|
if timer.expired?
|
23
23
|
raise 'Selenium is not running. ' \
|
24
|
-
|
25
|
-
|
24
|
+
"You can run a selenium server easily with: \n " \
|
25
|
+
'$ docker-compose up -d selenium_chrome'
|
26
26
|
else
|
27
27
|
puts 'Waiting for Selenium docker instance...'
|
28
28
|
sleep 1
|
@@ -32,18 +32,17 @@ def ensure_selenium_running!
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def selenium_gte?(version)
|
35
|
-
defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION
|
35
|
+
defined?(Selenium::WebDriver::VERSION) && (Gem::Version.new(Selenium::WebDriver::VERSION) >= Gem::Version.new(version))
|
36
36
|
end
|
37
37
|
|
38
38
|
Capybara.register_driver :selenium_chrome_remote do |app|
|
39
39
|
ensure_selenium_running!
|
40
40
|
|
41
41
|
url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
|
42
|
-
browser_options =
|
42
|
+
browser_options = Selenium::WebDriver::Chrome::Options.new
|
43
43
|
|
44
44
|
Capybara::Selenium::Driver.new app,
|
45
45
|
browser: :remote,
|
46
|
-
desired_capabilities: :chrome,
|
47
46
|
options: browser_options,
|
48
47
|
url: url
|
49
48
|
end
|
@@ -58,12 +57,10 @@ skipped_tests = %i[response_headers status_code trigger download]
|
|
58
57
|
|
59
58
|
Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
|
60
59
|
case example.metadata[:full_description]
|
61
|
-
when
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
when /node #right_click delay should delay the mouse up/
|
66
|
-
skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
|
60
|
+
when /Capybara::Session selenium_chrome_remote node #shadow_root should get visible text/
|
61
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
62
|
+
when /Capybara::Session selenium_chrome_remote node #shadow_root/
|
63
|
+
skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
|
67
64
|
end
|
68
65
|
end
|
69
66
|
|
@@ -78,23 +75,22 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
|
|
78
75
|
end
|
79
76
|
|
80
77
|
describe 'log access' do
|
81
|
-
|
78
|
+
let(:logs) do
|
79
|
+
session.driver.browser.then do |chrome_driver|
|
80
|
+
chrome_driver.respond_to?(:logs) ? chrome_driver : chrome_driver.manage
|
81
|
+
end.logs
|
82
|
+
end
|
82
83
|
|
83
84
|
it 'does not error when getting log types' do
|
84
|
-
skip unless Gem::Requirement.new('>= 75.0.3770.90').satisfied_by? chromedriver_version
|
85
85
|
expect do
|
86
|
-
|
86
|
+
logs.available_types
|
87
87
|
end.not_to raise_error
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'does not error when getting logs' do
|
91
91
|
expect do
|
92
|
-
|
92
|
+
logs.get(:browser)
|
93
93
|
end.not_to raise_error
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
97
|
-
def chromedriver_version
|
98
|
-
Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
|
99
|
-
end
|
100
96
|
end
|
data/spec/selenium_spec_edge.rb
CHANGED
@@ -10,15 +10,26 @@ require 'rspec/shared_spec_matchers'
|
|
10
10
|
# Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
|
11
11
|
# end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
Selenium::WebDriver.logger.ignore(:selenium_manager)
|
14
|
+
|
15
|
+
if Selenium::WebDriver::Platform.mac?
|
16
|
+
Selenium::WebDriver::Edge.path = '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'
|
15
17
|
end
|
16
18
|
|
17
19
|
Capybara.register_driver :selenium_edge do |app|
|
18
20
|
# ::Selenium::WebDriver.logger.level = "debug"
|
19
21
|
# If we don't create an options object the path set above won't be used
|
20
|
-
|
21
|
-
|
22
|
+
|
23
|
+
# browser_options = Selenium::WebDriver::Edge::Options.new
|
24
|
+
# browser_options.add_argument('--headless') if ENV['HEADLESS']
|
25
|
+
|
26
|
+
browser_options = if ENV['HEADLESS']
|
27
|
+
Selenium::WebDriver::Options.edge(args: ['--headless=new'])
|
28
|
+
else
|
29
|
+
Selenium::WebDriver::Options.edge
|
30
|
+
end
|
31
|
+
|
32
|
+
Capybara::Selenium::Driver.new(app, browser: :edge, options: browser_options).tap do |driver|
|
22
33
|
driver.browser
|
23
34
|
driver.download_path = Capybara.save_path
|
24
35
|
end
|
@@ -30,12 +41,14 @@ end
|
|
30
41
|
|
31
42
|
skipped_tests = %i[response_headers status_code trigger]
|
32
43
|
|
33
|
-
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::
|
44
|
+
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Edge) if ENV['CI']
|
34
45
|
|
35
46
|
Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
|
36
47
|
case example.metadata[:full_description]
|
37
48
|
when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
|
38
|
-
pending "
|
49
|
+
pending "Edge doesn't allow clicking on file inputs"
|
50
|
+
when /Capybara::Session selenium node #shadow_root should get visible text/
|
51
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
39
52
|
end
|
40
53
|
end
|
41
54
|
|
@@ -6,8 +6,10 @@ require 'shared_selenium_session'
|
|
6
6
|
require 'shared_selenium_node'
|
7
7
|
require 'rspec/shared_spec_matchers'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
Selenium::WebDriver.logger.ignore(:selenium_manager)
|
10
|
+
|
11
|
+
browser_options = Selenium::WebDriver::Firefox::Options.new
|
12
|
+
browser_options.add_argument '-headless' if ENV['HEADLESS']
|
11
13
|
# browser_options.add_option("log", {"level": "trace"})
|
12
14
|
|
13
15
|
browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |profile|
|
@@ -15,6 +17,7 @@ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof
|
|
15
17
|
profile['browser.download.folderList'] = 2
|
16
18
|
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
|
17
19
|
profile['browser.startup.homepage'] = 'about:blank' # workaround bug in Selenium 4 alpha4-7
|
20
|
+
profile['accessibility.tabfocus'] = 7 # make tab move over links too
|
18
21
|
end
|
19
22
|
|
20
23
|
Capybara.register_driver :selenium_firefox do |app|
|
@@ -59,18 +62,33 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
|
|
59
62
|
when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty'
|
60
63
|
pending "FF < 62 doesn't support setting all files at once" if firefox_lt?(62, @session)
|
61
64
|
when 'Capybara::Session selenium #accept_confirm should work with nested modals'
|
62
|
-
skip 'Broken in 63 <= FF < 69
|
63
|
-
skip 'Hangs in 69 <= FF < 71
|
64
|
-
skip 'Broken again intermittently in FF 71 - jus skip it'
|
65
|
+
skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
|
66
|
+
skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
|
67
|
+
skip 'Broken again intermittently in FF 71 - jus skip it' if firefox_lt?(109, @session) # don't really know when it was fixed
|
65
68
|
when 'Capybara::Session selenium #click_link can download a file'
|
66
69
|
skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
|
67
70
|
when 'Capybara::Session selenium #reset_session! removes ALL cookies'
|
68
71
|
pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
|
69
72
|
when /drag_to.*HTML5/
|
70
|
-
pending "Firefox < 62 doesn't support a DataTransfer
|
73
|
+
pending "Firefox < 62 doesn't support a DataTransfer constructor" if firefox_lt?(62.0, @session)
|
71
74
|
when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
|
72
75
|
'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
|
73
|
-
skip 'No clue what Firefox is doing here - works fine on MacOS locally'
|
76
|
+
skip 'No clue what Firefox is doing here - works fine on MacOS locally' if firefox_lt?(109, @session) # don't really know when it was fixed
|
77
|
+
when 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
|
78
|
+
'Capybara::Session selenium node #shadow_root should find nested shadow roots',
|
79
|
+
'Capybara::Session selenium node #shadow_root should click on elements',
|
80
|
+
'Capybara::Session selenium node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
|
81
|
+
'Capybara::Session selenium node #shadow_root should produce error messages when failing',
|
82
|
+
'Capybara::Session with firefox with selenium driver #evaluate_script returns a shadow root'
|
83
|
+
pending "Firefox doesn't yet have full W3C shadow root support" if firefox_lt?(113, @session)
|
84
|
+
when 'Capybara::Session selenium #fill_in should handle carriage returns with line feeds in a textarea correctly'
|
85
|
+
pending 'Not sure what firefox is doing here'
|
86
|
+
when /Capybara::Session selenium node #shadow_root should get visible text/
|
87
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
88
|
+
when /Capybara::Session selenium node #shadow_root/
|
89
|
+
skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
|
90
|
+
when /Capybara::Session selenium node #set should submit single text input forms if ended with \\n/
|
91
|
+
pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
|
74
92
|
end
|
75
93
|
end
|
76
94
|
|
@@ -102,7 +120,7 @@ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/Multi
|
|
102
120
|
end
|
103
121
|
|
104
122
|
it 'should fill in a datetime input with a String' do
|
105
|
-
|
123
|
+
pending 'Need to figure out what string format this will actually accept'
|
106
124
|
session.fill_in('form_datetime', with: datetime.iso8601)
|
107
125
|
session.click_button('awesome')
|
108
126
|
expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
|