capybara 3.23.0 → 3.35.3
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 +264 -11
- data/README.md +10 -6
- data/lib/capybara.rb +20 -8
- data/lib/capybara/config.rb +10 -8
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/driver/node.rb +4 -0
- data/lib/capybara/dsl.rb +10 -2
- data/lib/capybara/helpers.rb +28 -2
- data/lib/capybara/minitest.rb +232 -144
- data/lib/capybara/minitest/spec.rb +156 -97
- data/lib/capybara/node/actions.rb +36 -36
- data/lib/capybara/node/base.rb +6 -6
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +77 -33
- data/lib/capybara/node/finders.rb +24 -17
- data/lib/capybara/node/matchers.rb +79 -64
- data/lib/capybara/node/simple.rb +11 -4
- data/lib/capybara/queries/ancestor_query.rb +6 -10
- data/lib/capybara/queries/base_query.rb +2 -1
- data/lib/capybara/queries/current_path_query.rb +14 -4
- data/lib/capybara/queries/selector_query.rb +259 -23
- data/lib/capybara/queries/sibling_query.rb +5 -11
- data/lib/capybara/queries/style_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +13 -1
- data/lib/capybara/rack_test/browser.rb +13 -4
- data/lib/capybara/rack_test/driver.rb +2 -1
- data/lib/capybara/rack_test/form.rb +2 -2
- data/lib/capybara/rack_test/node.rb +42 -6
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/drivers.rb +18 -12
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +9 -2
- data/lib/capybara/result.rb +39 -19
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/rspec/matcher_proxies.rb +5 -5
- data/lib/capybara/rspec/matchers.rb +97 -74
- data/lib/capybara/rspec/matchers/base.rb +19 -6
- data/lib/capybara/rspec/matchers/count_sugar.rb +2 -1
- data/lib/capybara/rspec/matchers/have_ancestor.rb +5 -7
- data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
- data/lib/capybara/rspec/matchers/have_selector.rb +15 -10
- data/lib/capybara/rspec/matchers/have_sibling.rb +4 -7
- data/lib/capybara/rspec/matchers/have_text.rb +4 -7
- data/lib/capybara/rspec/matchers/have_title.rb +2 -2
- data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
- data/lib/capybara/rspec/matchers/match_style.rb +7 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/selector.rb +46 -19
- data/lib/capybara/selector/builders/css_builder.rb +10 -6
- data/lib/capybara/selector/builders/xpath_builder.rb +4 -2
- data/lib/capybara/selector/css.rb +1 -1
- data/lib/capybara/selector/definition.rb +13 -11
- data/lib/capybara/selector/definition/button.rb +32 -15
- data/lib/capybara/selector/definition/checkbox.rb +2 -2
- data/lib/capybara/selector/definition/css.rb +3 -1
- data/lib/capybara/selector/definition/datalist_input.rb +2 -2
- data/lib/capybara/selector/definition/datalist_option.rb +1 -1
- data/lib/capybara/selector/definition/element.rb +3 -2
- data/lib/capybara/selector/definition/field.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +2 -2
- data/lib/capybara/selector/definition/label.rb +5 -3
- data/lib/capybara/selector/definition/link.rb +8 -0
- data/lib/capybara/selector/definition/option.rb +1 -1
- data/lib/capybara/selector/definition/radio_button.rb +2 -2
- data/lib/capybara/selector/definition/select.rb +33 -14
- data/lib/capybara/selector/definition/table.rb +6 -3
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/filter_set.rb +13 -11
- data/lib/capybara/selector/filters/base.rb +6 -1
- data/lib/capybara/selector/filters/locator_filter.rb +1 -1
- data/lib/capybara/selector/regexp_disassembler.rb +7 -0
- data/lib/capybara/selector/selector.rb +13 -3
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -1
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -1
- data/lib/capybara/selenium/atoms/src/getAttribute.js +1 -1
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +10 -10
- data/lib/capybara/selenium/driver.rb +86 -24
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +24 -21
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +21 -19
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +17 -1
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +0 -4
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +37 -26
- data/lib/capybara/selenium/extensions/html5_drag.rb +55 -11
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +8 -10
- data/lib/capybara/selenium/logger_suppressor.rb +8 -2
- data/lib/capybara/selenium/node.rb +160 -40
- data/lib/capybara/selenium/nodes/chrome_node.rb +72 -12
- data/lib/capybara/selenium/nodes/edge_node.rb +32 -14
- data/lib/capybara/selenium/nodes/firefox_node.rb +28 -32
- data/lib/capybara/selenium/nodes/safari_node.rb +5 -29
- data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +4 -4
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +32 -7
- data/lib/capybara/server.rb +19 -3
- data/lib/capybara/server/animation_disabler.rb +8 -3
- data/lib/capybara/server/checker.rb +1 -1
- data/lib/capybara/server/middleware.rb +22 -10
- data/lib/capybara/session.rb +66 -40
- data/lib/capybara/session/config.rb +11 -3
- data/lib/capybara/session/matchers.rb +11 -11
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +75 -7
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
- data/lib/capybara/spec/session/all_spec.rb +60 -5
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
- data/lib/capybara/spec/session/check_spec.rb +6 -0
- data/lib/capybara/spec/session/click_button_spec.rb +16 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/current_url_spec.rb +11 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +29 -0
- data/lib/capybara/spec/session/find_spec.rb +55 -0
- data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -0
- data/lib/capybara/spec/session/has_button_spec.rb +51 -0
- data/lib/capybara/spec/session/has_css_spec.rb +26 -4
- data/lib/capybara/spec/session/has_current_path_spec.rb +15 -2
- data/lib/capybara/spec/session/has_field_spec.rb +34 -0
- data/lib/capybara/spec/session/has_select_spec.rb +32 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
- data/lib/capybara/spec/session/has_table_spec.rb +51 -5
- data/lib/capybara/spec/session/has_text_spec.rb +30 -0
- data/lib/capybara/spec/session/html_spec.rb +1 -1
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
- data/lib/capybara/spec/session/node_spec.rb +394 -9
- data/lib/capybara/spec/session/refresh_spec.rb +2 -1
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +4 -4
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -15
- data/lib/capybara/spec/session/selectors_spec.rb +16 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +8 -8
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
- data/lib/capybara/spec/spec_helper.rb +14 -14
- data/lib/capybara/spec/test_app.rb +27 -21
- data/lib/capybara/spec/views/form.erb +47 -4
- data/lib/capybara/spec/views/offset.erb +32 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/with_animation.erb +37 -1
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_html.erb +24 -2
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +4 -1
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_sortable_js.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +3 -7
- data/spec/basic_node_spec.rb +15 -14
- data/spec/capybara_spec.rb +28 -28
- data/spec/dsl_spec.rb +16 -3
- data/spec/filter_set_spec.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
- data/spec/minitest_spec.rb +3 -2
- data/spec/minitest_spec_spec.rb +46 -46
- data/spec/rack_test_spec.rb +38 -15
- data/spec/regexp_dissassembler_spec.rb +52 -38
- data/spec/result_spec.rb +43 -32
- data/spec/rspec/features_spec.rb +4 -1
- data/spec/rspec/scenarios_spec.rb +4 -0
- data/spec/rspec/shared_spec_matchers.rb +68 -56
- data/spec/rspec_spec.rb +9 -5
- data/spec/selector_spec.rb +32 -17
- data/spec/selenium_spec_chrome.rb +78 -11
- data/spec/selenium_spec_chrome_remote.rb +23 -6
- data/spec/selenium_spec_edge.rb +15 -12
- data/spec/selenium_spec_firefox.rb +24 -19
- data/spec/selenium_spec_firefox_remote.rb +0 -8
- data/spec/selenium_spec_ie.rb +1 -6
- data/spec/server_spec.rb +106 -44
- data/spec/session_spec.rb +5 -5
- data/spec/shared_selenium_node.rb +56 -2
- data/spec/shared_selenium_session.rb +122 -15
- data/spec/spec_helper.rb +2 -2
- metadata +63 -17
- data/lib/capybara/spec/session/source_spec.rb +0 -0
data/spec/rspec_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable RSpec/MultipleDescribes
|
4
|
+
|
3
5
|
require 'spec_helper'
|
4
6
|
|
5
7
|
RSpec.describe 'capybara/rspec' do
|
@@ -43,7 +45,7 @@ RSpec.describe 'capybara/rspec' do
|
|
43
45
|
expect(Capybara.current_driver).to eq(:culerity)
|
44
46
|
end
|
45
47
|
|
46
|
-
|
48
|
+
describe '#all' do
|
47
49
|
it 'allows access to the Capybara finder' do
|
48
50
|
visit('/with_html')
|
49
51
|
found = all(:css, 'h2') { |element| element[:class] == 'head' }
|
@@ -57,7 +59,7 @@ RSpec.describe 'capybara/rspec' do
|
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
|
62
|
+
describe '#within' do
|
61
63
|
it 'allows access to the Capybara scoper' do
|
62
64
|
visit('/with_html')
|
63
65
|
expect do
|
@@ -76,13 +78,13 @@ RSpec.describe 'capybara/rspec' do
|
|
76
78
|
context 'Type: Other', type: :other do
|
77
79
|
context 'when RSpec::Matchers is included after Capybara::DSL' do
|
78
80
|
let(:test_class_instance) do
|
79
|
-
|
81
|
+
Class.new do
|
80
82
|
include Capybara::DSL
|
81
83
|
include RSpec::Matchers
|
82
84
|
end.new
|
83
85
|
end
|
84
86
|
|
85
|
-
|
87
|
+
describe '#all' do
|
86
88
|
it 'allows access to the Capybara finder' do
|
87
89
|
test_class_instance.visit('/with_html')
|
88
90
|
expect(test_class_instance.all(:css, 'h2.head').size).to eq(5)
|
@@ -95,7 +97,7 @@ RSpec.describe 'capybara/rspec' do
|
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
98
|
-
|
100
|
+
describe '#within' do
|
99
101
|
it 'allows access to the Capybara scoper' do
|
100
102
|
test_class_instance.visit('/with_html')
|
101
103
|
expect do
|
@@ -143,3 +145,5 @@ feature 'Feature DSL' do
|
|
143
145
|
expect(page.body).to include('Another World')
|
144
146
|
end
|
145
147
|
end
|
148
|
+
|
149
|
+
# rubocop:enable RSpec/MultipleDescribes
|
data/spec/selector_spec.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Capybara do
|
6
|
+
include Capybara::RSpecMatchers
|
6
7
|
describe 'Selectors' do
|
7
8
|
let :string do
|
8
|
-
|
9
|
+
described_class.string <<-STRING
|
9
10
|
<html>
|
10
11
|
<head>
|
11
12
|
<title>selectors</title>
|
@@ -69,12 +70,12 @@ RSpec.describe Capybara do
|
|
69
70
|
end
|
70
71
|
|
71
72
|
before do
|
72
|
-
|
73
|
+
described_class.add_selector :custom_selector do
|
73
74
|
css { |css_class| "div.#{css_class}" }
|
74
75
|
node_filter(:not_empty, boolean: true, default: true, skip_if: :all) { |node, value| value ^ (node.text == '') }
|
75
76
|
end
|
76
77
|
|
77
|
-
|
78
|
+
described_class.add_selector :custom_css_selector do
|
78
79
|
css(:name, :other_name) do |selector, name: nil, **|
|
79
80
|
selector ||= ''
|
80
81
|
selector += "[name='#{name}']" if name
|
@@ -94,7 +95,7 @@ RSpec.describe Capybara do
|
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
97
|
-
|
98
|
+
described_class.add_selector :custom_xpath_selector do
|
98
99
|
xpath(:valid1, :valid2) { |selector| selector }
|
99
100
|
match { |value| value == 'match_me' }
|
100
101
|
end
|
@@ -102,7 +103,7 @@ RSpec.describe Capybara do
|
|
102
103
|
|
103
104
|
it 'supports `filter` as an alias for `node_filter`' do
|
104
105
|
expect do
|
105
|
-
|
106
|
+
described_class.add_selector :filter_alias_selector do
|
106
107
|
css { |_unused| 'div' }
|
107
108
|
filter(:something) { |_node, _value| true }
|
108
109
|
end
|
@@ -111,7 +112,7 @@ RSpec.describe Capybara do
|
|
111
112
|
|
112
113
|
describe 'adding a selector' do
|
113
114
|
it 'can set default visiblity' do
|
114
|
-
|
115
|
+
described_class.add_selector :hidden_field do
|
115
116
|
visible :hidden
|
116
117
|
css { |_sel| 'input[type="hidden"]' }
|
117
118
|
end
|
@@ -125,7 +126,7 @@ RSpec.describe Capybara do
|
|
125
126
|
it 'allows modifying a selector' do
|
126
127
|
el = string.find(:custom_selector, 'aa')
|
127
128
|
expect(el.tag_name).to eq 'div'
|
128
|
-
|
129
|
+
described_class.modify_selector :custom_selector do
|
129
130
|
css { |css_class| "h1.#{css_class}" }
|
130
131
|
end
|
131
132
|
el = string.find(:custom_selector, 'aa')
|
@@ -133,7 +134,7 @@ RSpec.describe Capybara do
|
|
133
134
|
end
|
134
135
|
|
135
136
|
it "doesn't change existing filters" do
|
136
|
-
|
137
|
+
described_class.modify_selector :custom_selector do
|
137
138
|
css { |css_class| "p.#{css_class}" }
|
138
139
|
end
|
139
140
|
expect(string).to have_selector(:custom_selector, 'bb', count: 1)
|
@@ -164,7 +165,7 @@ RSpec.describe Capybara do
|
|
164
165
|
|
165
166
|
describe 'xpath' do
|
166
167
|
it 'uses filter names passed in' do
|
167
|
-
|
168
|
+
described_class.add_selector :test do
|
168
169
|
xpath(:something, :other) { |_locator| XPath.descendant }
|
169
170
|
end
|
170
171
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -173,7 +174,7 @@ RSpec.describe Capybara do
|
|
173
174
|
end
|
174
175
|
|
175
176
|
it 'gets filter names from block if none passed to xpath method' do
|
176
|
-
|
177
|
+
described_class.add_selector :test do
|
177
178
|
xpath { |_locator, valid3:, valid4: nil| "#{valid3} #{valid4}" }
|
178
179
|
end
|
179
180
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -182,7 +183,7 @@ RSpec.describe Capybara do
|
|
182
183
|
end
|
183
184
|
|
184
185
|
it 'ignores block parameters if names passed in' do
|
185
|
-
|
186
|
+
described_class.add_selector :test do
|
186
187
|
xpath(:valid1) { |_locator, valid3:, valid4: nil| "#{valid3} #{valid4}" }
|
187
188
|
end
|
188
189
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -205,7 +206,7 @@ RSpec.describe Capybara do
|
|
205
206
|
end
|
206
207
|
|
207
208
|
it 'uses filter names passed in' do
|
208
|
-
|
209
|
+
described_class.add_selector :test do
|
209
210
|
css(:name, :other_name) { |_locator| '' }
|
210
211
|
end
|
211
212
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -214,7 +215,7 @@ RSpec.describe Capybara do
|
|
214
215
|
end
|
215
216
|
|
216
217
|
it 'gets filter names from block if none passed to css method' do
|
217
|
-
|
218
|
+
described_class.add_selector :test do
|
218
219
|
css { |_locator, valid3:, valid4: nil| "#{valid3} #{valid4}" }
|
219
220
|
end
|
220
221
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -223,7 +224,7 @@ RSpec.describe Capybara do
|
|
223
224
|
end
|
224
225
|
|
225
226
|
it 'ignores block parameters if names passed in' do
|
226
|
-
|
227
|
+
described_class.add_selector :test do
|
227
228
|
css(:valid1) { |_locator, valid3:, valid4: nil| "#{valid3} #{valid4}" }
|
228
229
|
end
|
229
230
|
selector = Capybara::Selector.new :test, config: nil, format: nil
|
@@ -326,9 +327,23 @@ RSpec.describe Capybara do
|
|
326
327
|
expect(string.find(:custom_xpath_selector, './/div', class: /dOm WoR/i)[:id]).to eq 'random_words'
|
327
328
|
end
|
328
329
|
|
329
|
-
it 'accepts Regexp for CSS
|
330
|
+
it 'accepts Regexp for CSS based selectors' do
|
330
331
|
expect(string.find(:custom_css_selector, 'div', class: /random/)[:id]).to eq 'random_words'
|
331
332
|
end
|
333
|
+
|
334
|
+
it 'accepts Regexp for individual class names for XPath based selectors' do
|
335
|
+
expect(string.find(:custom_xpath_selector, './/div', class: [/random/, 'some'])[:id]).to eq 'random_words'
|
336
|
+
expect(string.find(:custom_xpath_selector, './/div', class: [/om/, /wor/])[:id]).to eq 'random_words'
|
337
|
+
expect { string.find(:custom_xpath_selector, './/div', class: [/not/, /wor/]) }.to raise_error(Capybara::ElementNotFound)
|
338
|
+
expect { string.find(:custom_xpath_selector, './/div', class: [/dom wor/]) }.to raise_error(Capybara::ElementNotFound)
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'accepts Regexp for individual class names for CSS based selectors' do
|
342
|
+
expect(string.find(:custom_css_selector, 'div', class: [/random/])[:id]).to eq 'random_words'
|
343
|
+
expect(string.find(:custom_css_selector, 'div', class: [/om/, /wor/, 'some'])[:id]).to eq 'random_words'
|
344
|
+
expect { string.find(:custom_css_selector, 'div', class: [/not/, /wor/]) }.to raise_error(Capybara::ElementNotFound)
|
345
|
+
expect { string.find(:custom_css_selector, 'div', class: [/dom wor/]) }.to raise_error(Capybara::ElementNotFound)
|
346
|
+
end
|
332
347
|
end
|
333
348
|
|
334
349
|
context 'with :style option' do
|
@@ -476,8 +491,8 @@ RSpec.describe Capybara do
|
|
476
491
|
end
|
477
492
|
|
478
493
|
describe ':link_or_button selector' do
|
479
|
-
around
|
480
|
-
|
494
|
+
around do |example|
|
495
|
+
described_class.modify_selector(:link_or_button) do
|
481
496
|
expression_filter(:random) { |xpath, _| xpath } # do nothing filter
|
482
497
|
end
|
483
498
|
example.run
|
@@ -13,24 +13,62 @@ Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV['CI'] &&
|
|
13
13
|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
14
14
|
browser_options.headless! if ENV['HEADLESS']
|
15
15
|
browser_options.add_option(:w3c, ENV['W3C'] != 'false')
|
16
|
+
# Chromedriver 77 requires setting this for headless mode on linux
|
17
|
+
# Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
|
18
|
+
browser_options.add_preference('download.default_directory', Capybara.save_path)
|
19
|
+
browser_options.add_preference(:download, default_directory: Capybara.save_path)
|
16
20
|
|
17
21
|
Capybara.register_driver :selenium_chrome do |app|
|
18
|
-
Capybara::Selenium::Driver.
|
22
|
+
version = Capybara::Selenium::Driver.load_selenium
|
23
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
24
|
+
driver_options = { browser: :chrome, timeout: 30 }.tap do |opts|
|
25
|
+
opts[options_key] = browser_options
|
26
|
+
end
|
27
|
+
|
28
|
+
Capybara::Selenium::Driver.new(app, **driver_options).tap do |driver|
|
29
|
+
# Set download dir for Chrome < 77
|
19
30
|
driver.browser.download_path = Capybara.save_path
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
23
34
|
Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
35
|
+
version = Capybara::Selenium::Driver.load_selenium
|
36
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
37
|
+
chrome_options = { browser: :chrome, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
|
38
|
+
opts[options_key] = browser_options
|
39
|
+
end
|
40
|
+
|
41
|
+
Capybara::Selenium::Driver.new(app, **chrome_options)
|
42
|
+
end
|
43
|
+
|
44
|
+
Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
|
45
|
+
version = Capybara::Selenium::Driver.load_selenium
|
46
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
47
|
+
chrome_options = { browser: :chrome, clear_session_storage: false }.tap do |opts|
|
48
|
+
opts[options_key] = browser_options
|
49
|
+
end
|
50
|
+
|
51
|
+
Capybara::Selenium::Driver.new(app, **chrome_options)
|
52
|
+
end
|
53
|
+
|
54
|
+
Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
|
55
|
+
version = Capybara::Selenium::Driver.load_selenium
|
56
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
57
|
+
chrome_options = { browser: :chrome, clear_local_storage: false }.tap do |opts|
|
58
|
+
opts[options_key] = browser_options
|
59
|
+
end
|
60
|
+
Capybara::Selenium::Driver.new(app, **chrome_options)
|
29
61
|
end
|
30
62
|
|
31
63
|
Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
|
64
|
+
version = Capybara::Selenium::Driver.load_selenium
|
65
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
32
66
|
subclass = Class.new(Capybara::Selenium::Driver)
|
33
|
-
|
67
|
+
chrome_options = { browser: :chrome, timeout: 30 }.tap do |opts|
|
68
|
+
opts[options_key] = browser_options
|
69
|
+
end
|
70
|
+
|
71
|
+
subclass.new(app, **chrome_options)
|
34
72
|
end
|
35
73
|
|
36
74
|
module TestSessions
|
@@ -47,6 +85,10 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
|
|
47
85
|
skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
|
48
86
|
when /Capybara::Session selenium_chrome Capybara::Window#maximize/
|
49
87
|
pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
|
88
|
+
when /Capybara::Window#fullscreen should be able to fullscreen the window/
|
89
|
+
skip 'Chromedriver hangs on attempts to fullscreen in headless mode' if ENV['HEADLESS']
|
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'
|
50
92
|
end
|
51
93
|
end
|
52
94
|
|
@@ -77,6 +119,26 @@ RSpec.describe 'Capybara::Session with chrome' do
|
|
77
119
|
expect(session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
|
78
120
|
expect(session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
|
79
121
|
end
|
122
|
+
|
123
|
+
it 'can not clear session storage' do
|
124
|
+
session = Capybara::Session.new(:selenium_chrome_not_clear_session_storage, TestApp)
|
125
|
+
session.visit('/with_js')
|
126
|
+
session.find(:css, '#set-storage').click
|
127
|
+
session.reset!
|
128
|
+
session.visit('/with_js')
|
129
|
+
expect(session.evaluate_script('Object.keys(localStorage)')).to be_empty
|
130
|
+
expect(session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'can not clear local storage' do
|
134
|
+
session = Capybara::Session.new(:selenium_chrome_not_clear_local_storage, TestApp)
|
135
|
+
session.visit('/with_js')
|
136
|
+
session.find(:css, '#set-storage').click
|
137
|
+
session.reset!
|
138
|
+
session.visit('/with_js')
|
139
|
+
expect(session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
|
140
|
+
expect(session.evaluate_script('Object.keys(sessionStorage)')).to be_empty
|
141
|
+
end
|
80
142
|
end
|
81
143
|
end
|
82
144
|
|
@@ -125,16 +187,21 @@ RSpec.describe 'Capybara::Session with chrome' do
|
|
125
187
|
describe 'log access' do
|
126
188
|
before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
|
127
189
|
|
128
|
-
it '
|
190
|
+
it 'does not error getting log types' do
|
191
|
+
skip if Gem::Requirement.new('< 75.0.3770.90').satisfied_by? chromedriver_version
|
129
192
|
expect do
|
130
193
|
session.driver.browser.manage.logs.available_types
|
131
|
-
end.
|
194
|
+
end.not_to raise_error
|
132
195
|
end
|
133
196
|
|
134
|
-
it '
|
197
|
+
it 'does not error when getting logs' do
|
135
198
|
expect do
|
136
199
|
session.driver.browser.manage.logs.get(:browser)
|
137
|
-
end.
|
200
|
+
end.not_to raise_error
|
138
201
|
end
|
139
202
|
end
|
203
|
+
|
204
|
+
def chromedriver_version
|
205
|
+
Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
|
206
|
+
end
|
140
207
|
end
|
@@ -54,12 +54,6 @@ module TestSessions
|
|
54
54
|
Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
|
55
55
|
end
|
56
56
|
|
57
|
-
TestSessions::Chrome.driver.browser.file_detector = lambda do |args|
|
58
|
-
# args => ["/path/to/file"]
|
59
|
-
str = args.first.to_s
|
60
|
-
str if File.exist?(str)
|
61
|
-
end
|
62
|
-
|
63
57
|
skipped_tests = %i[response_headers status_code trigger download]
|
64
58
|
|
65
59
|
Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
|
@@ -68,6 +62,8 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s,
|
|
68
62
|
'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded',
|
69
63
|
'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty'
|
70
64
|
pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14)
|
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'
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
@@ -80,4 +76,25 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
|
|
80
76
|
it 'is considered to be chrome' do
|
81
77
|
expect(session.driver.browser.browser).to eq :chrome
|
82
78
|
end
|
79
|
+
|
80
|
+
describe 'log access' do
|
81
|
+
before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
|
82
|
+
|
83
|
+
it 'does not error when getting log types' do
|
84
|
+
skip unless Gem::Requirement.new('>= 75.0.3770.90').satisfied_by? chromedriver_version
|
85
|
+
expect do
|
86
|
+
session.driver.browser.manage.logs.available_types
|
87
|
+
end.not_to raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'does not error when getting logs' do
|
91
|
+
expect do
|
92
|
+
session.driver.browser.manage.logs.get(:browser)
|
93
|
+
end.not_to raise_error
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def chromedriver_version
|
98
|
+
Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
|
99
|
+
end
|
83
100
|
end
|
data/spec/selenium_spec_edge.rb
CHANGED
@@ -6,12 +6,19 @@ require 'shared_selenium_session'
|
|
6
6
|
require 'shared_selenium_node'
|
7
7
|
require 'rspec/shared_spec_matchers'
|
8
8
|
|
9
|
-
|
10
|
-
Selenium::WebDriver::
|
9
|
+
# unless ENV['CI']
|
10
|
+
# Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
|
11
|
+
# end
|
12
|
+
|
13
|
+
if ::Selenium::WebDriver::Platform.mac?
|
14
|
+
Selenium::WebDriver::EdgeChrome.path = '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev'
|
15
|
+
end
|
11
16
|
|
12
17
|
Capybara.register_driver :selenium_edge do |app|
|
13
18
|
# ::Selenium::WebDriver.logger.level = "debug"
|
14
|
-
|
19
|
+
# If we don't create an options object the path set above won't be used
|
20
|
+
browser_options = ::Selenium::WebDriver::EdgeChrome::Options.new
|
21
|
+
Capybara::Selenium::Driver.new(app, browser: :edge_chrome, options: browser_options).tap do |driver|
|
15
22
|
driver.browser
|
16
23
|
driver.download_path = Capybara.save_path
|
17
24
|
end
|
@@ -23,17 +30,13 @@ end
|
|
23
30
|
|
24
31
|
skipped_tests = %i[response_headers status_code trigger]
|
25
32
|
|
26
|
-
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::
|
33
|
+
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::EdgeChrome) if ENV['CI']
|
27
34
|
|
28
35
|
Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
# skip 'Crashes'
|
34
|
-
# when /when Capybara.always_include_port is true/
|
35
|
-
# skip 'Crashes'
|
36
|
-
# end
|
36
|
+
case example.metadata[:full_description]
|
37
|
+
when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
|
38
|
+
pending "EdgeChrome doesn't allow clicking on file inputs"
|
39
|
+
end
|
37
40
|
end
|
38
41
|
|
39
42
|
RSpec.describe 'Capybara::Session with Edge', capybara_skip: skipped_tests do
|
@@ -14,28 +14,30 @@ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof
|
|
14
14
|
profile['browser.download.dir'] = Capybara.save_path
|
15
15
|
profile['browser.download.folderList'] = 2
|
16
16
|
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
|
17
|
+
profile['browser.startup.homepage'] = 'about:blank' # workaround bug in Selenium 4 alpha4-7
|
17
18
|
end
|
18
19
|
|
19
20
|
Capybara.register_driver :selenium_firefox do |app|
|
20
21
|
# ::Selenium::WebDriver.logger.level = "debug"
|
21
|
-
Capybara::Selenium::Driver.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
timeout: 31
|
22
|
+
version = Capybara::Selenium::Driver.load_selenium
|
23
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
24
|
+
driver_options = { browser: :firefox, timeout: 31 }.tap do |opts|
|
25
|
+
opts[options_key] = browser_options
|
26
26
|
# Get a trace level log from geckodriver
|
27
27
|
# :driver_opts => { args: ['-vv'] }
|
28
|
-
|
28
|
+
end
|
29
|
+
|
30
|
+
Capybara::Selenium::Driver.new(app, **driver_options)
|
29
31
|
end
|
30
32
|
|
31
33
|
Capybara.register_driver :selenium_firefox_not_clear_storage do |app|
|
32
|
-
Capybara::Selenium::Driver.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
)
|
34
|
+
version = Capybara::Selenium::Driver.load_selenium
|
35
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
36
|
+
driver_options = { browser: :firefox, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
|
37
|
+
opts[options_key] = browser_options
|
38
|
+
end
|
39
|
+
|
40
|
+
Capybara::Selenium::Driver.new(app, **driver_options)
|
39
41
|
end
|
40
42
|
|
41
43
|
module TestSessions
|
@@ -49,7 +51,7 @@ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Firefox) i
|
|
49
51
|
Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capybara_skip: skipped_tests do |example|
|
50
52
|
case example.metadata[:full_description]
|
51
53
|
when 'Capybara::Session selenium node #click should allow multiple modifiers'
|
52
|
-
pending "Firefox doesn't generate an event for shift+control+click" if firefox_gte?(62, @session) &&
|
54
|
+
pending "Firefox on OSX doesn't generate an event for shift+control+click" if firefox_gte?(62, @session) && Selenium::WebDriver::Platform.mac?
|
53
55
|
when /^Capybara::Session selenium node #double_click/
|
54
56
|
pending "selenium-webdriver/geckodriver doesn't generate double click event" if firefox_lt?(59, @session)
|
55
57
|
when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default'
|
@@ -57,15 +59,18 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
|
|
57
59
|
when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty'
|
58
60
|
pending "FF < 62 doesn't support setting all files at once" if firefox_lt?(62, @session)
|
59
61
|
when 'Capybara::Session selenium #accept_confirm should work with nested modals'
|
60
|
-
skip 'Broken in FF
|
62
|
+
skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
|
63
|
+
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)
|
64
|
+
skip 'Broken again intermittently in FF 71 - jus skip it'
|
61
65
|
when 'Capybara::Session selenium #click_link can download a file'
|
62
66
|
skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
|
63
67
|
when 'Capybara::Session selenium #reset_session! removes ALL cookies'
|
64
68
|
pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
|
65
|
-
when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
|
66
|
-
pending "Geckodriver doesn't allow clicking on file inputs"
|
67
69
|
when /drag_to.*HTML5/
|
68
70
|
pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
|
71
|
+
when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
|
72
|
+
'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'
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
@@ -106,7 +111,7 @@ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/Multi
|
|
106
111
|
end
|
107
112
|
|
108
113
|
RSpec.describe Capybara::Selenium::Driver do
|
109
|
-
let(:driver) {
|
114
|
+
let(:driver) { described_class.new(TestApp, browser: :firefox, options: browser_options) }
|
110
115
|
|
111
116
|
describe '#quit' do
|
112
117
|
it 'should reset browser when quit' do
|
@@ -183,7 +188,7 @@ RSpec.describe Capybara::Selenium::Driver do
|
|
183
188
|
end
|
184
189
|
|
185
190
|
RSpec.describe Capybara::Selenium::Node do
|
186
|
-
|
191
|
+
describe '#click' do
|
187
192
|
it 'warns when attempting on a table row' do
|
188
193
|
session = TestSessions::SeleniumFirefox
|
189
194
|
session.visit('/tables')
|