capybara 3.14.0 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +13 -0
  3. data/README.md +2 -1
  4. data/lib/capybara/node/actions.rb +37 -6
  5. data/lib/capybara/node/matchers.rb +10 -2
  6. data/lib/capybara/selector.rb +117 -1
  7. data/lib/capybara/selector/selector.rb +7 -0
  8. data/lib/capybara/selector/xpath_extensions.rb +9 -0
  9. data/lib/capybara/selenium/driver.rb +13 -2
  10. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +15 -0
  11. data/lib/capybara/selenium/extensions/find.rb +2 -1
  12. data/lib/capybara/selenium/node.rb +1 -1
  13. data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
  14. data/lib/capybara/selenium/nodes/safari_node.rb +145 -0
  15. data/lib/capybara/spec/session/attach_file_spec.rb +46 -27
  16. data/lib/capybara/spec/session/click_button_spec.rb +65 -60
  17. data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
  18. data/lib/capybara/spec/session/fill_in_spec.rb +3 -3
  19. data/lib/capybara/spec/session/find_spec.rb +5 -0
  20. data/lib/capybara/spec/session/has_table_spec.rb +120 -0
  21. data/lib/capybara/spec/session/node_spec.rb +3 -3
  22. data/lib/capybara/spec/session/reset_session_spec.rb +8 -7
  23. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  24. data/lib/capybara/spec/session/window/window_spec.rb +44 -48
  25. data/lib/capybara/spec/views/form.erb +5 -0
  26. data/lib/capybara/spec/views/tables.erb +67 -0
  27. data/lib/capybara/spec/views/with_html.erb +2 -2
  28. data/lib/capybara/spec/views/with_js.erb +1 -0
  29. data/lib/capybara/version.rb +1 -1
  30. data/spec/capybara_spec.rb +4 -4
  31. data/spec/css_builder_spec.rb +2 -0
  32. data/spec/dsl_spec.rb +13 -17
  33. data/spec/rack_test_spec.rb +77 -85
  34. data/spec/rspec/features_spec.rb +2 -0
  35. data/spec/rspec/shared_spec_matchers.rb +34 -35
  36. data/spec/rspec_spec.rb +11 -13
  37. data/spec/selector_spec.rb +31 -0
  38. data/spec/selenium_spec_chrome.rb +25 -25
  39. data/spec/selenium_spec_firefox.rb +62 -35
  40. data/spec/selenium_spec_firefox_remote.rb +2 -0
  41. data/spec/selenium_spec_safari.rb +148 -0
  42. data/spec/server_spec.rb +40 -44
  43. data/spec/shared_selenium_session.rb +27 -21
  44. data/spec/spec_helper.rb +4 -0
  45. data/spec/xpath_builder_spec.rb +2 -0
  46. metadata +7 -3
@@ -73,6 +73,8 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE
73
73
  when /#accept_confirm should work with nested modals$/
74
74
  # skip because this is timing based and hence flaky when set to pending
75
75
  skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session)
76
+ when 'Capybara::Session selenium_firefox_remote #attach_file with a block can upload by clicking the file input'
77
+ pending "Geckodriver doesn't allow clicking on file inputs"
76
78
  end
77
79
  end
78
80
 
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+ require 'shared_selenium_session'
6
+ require 'rspec/shared_spec_matchers'
7
+
8
+ SAFARI_DRIVER = :selenium_safari
9
+
10
+ ::Selenium::WebDriver::Safari.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
11
+
12
+ browser_options = ::Selenium::WebDriver::Safari::Options.new
13
+ # browser_options.headless! if ENV['HEADLESS']
14
+ # browser_options.add_option(:w3c, !!ENV['W3C'])
15
+
16
+ Capybara.register_driver :selenium_safari do |app|
17
+ Capybara::Selenium::Driver.new(app, browser: :safari, options: browser_options, timeout: 30).tap do |driver|
18
+ # driver.browser.download_path = Capybara.save_path
19
+ end
20
+ end
21
+
22
+ Capybara.register_driver :selenium_safari_not_clear_storage do |app|
23
+ safari_options = {
24
+ browser: :safari,
25
+ options: browser_options
26
+ }
27
+ Capybara::Selenium::Driver.new(app, safari_options.merge(clear_local_storage: false, clear_session_storage: false))
28
+ end
29
+
30
+ module TestSessions
31
+ Safari = Capybara::Session.new(SAFARI_DRIVER, TestApp)
32
+ end
33
+
34
+ skipped_tests = %i[response_headers status_code trigger windows drag]
35
+
36
+ $stdout.puts `#{Selenium::WebDriver::Safari.driver_path} --version` if ENV['CI']
37
+
38
+ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybara_skip: skipped_tests do |example|
39
+ case example.metadata[:full_description]
40
+ when /click_link can download a file/
41
+ skip "safaridriver doesn't provide a way to set the download directory"
42
+ when /Capybara::Session selenium_safari Capybara::Window#maximize/
43
+ pending "Safari headless doesn't support maximize" if ENV['HEADLESS']
44
+ when /Capybara::Session selenium_safari #visit without a server/,
45
+ /Capybara::Session selenium_safari #visit with Capybara.app_host set should override server/,
46
+ /Capybara::Session selenium_safari #reset_session! When reuse_server == false raises any standard errors caught inside the server during a second session/
47
+ skip "Safari webdriver doesn't support multiple sessions"
48
+ when /Capybara::Session selenium_safari #click_link with alternative text given to a contained image/,
49
+ 'Capybara::Session selenium_safari #click_link_or_button with enable_aria_label should click on link'
50
+ pending 'safaridriver thinks these links are non-interactable for some unknown reason'
51
+ when /Capybara::Session selenium_safari #attach_file with a block can upload by clicking the file input/
52
+ skip "safaridriver doesn't allow clicking on file inputs"
53
+ when /Capybara::Session selenium_safari #attach_file with a block can upload by clicking the label/
54
+ skip 'hangs tests'
55
+ when /Capybara::Session selenium_safari #check when checkbox hidden with Capybara.automatic_label_click == false with allow_label_click == true should check via the label if input is visible but blocked by another element/,
56
+ 'Capybara::Session selenium_safari node #click should not retry clicking when wait is disabled',
57
+ 'Capybara::Session selenium_safari node #click should allow to retry longer',
58
+ 'Capybara::Session selenium_safari node #click should retry clicking'
59
+ pending "safaridriver doesn't return a specific enough error to deal with this"
60
+ when /Capybara::Session selenium_safari #within_frame should find multiple nested frames/,
61
+ /Capybara::Session selenium_safari #within_frame works if the frame is closed/,
62
+ /Capybara::Session selenium_safari #switch_to_frame works if the frame is closed/
63
+ skip 'switch_to_frame(:parent) appears to go to the root in Safari rather than parent'
64
+ when /Capybara::Session selenium_safari #reset_session! removes ALL cookies/
65
+ skip 'Safari webdriver can only remove cookies for the current domain'
66
+ when /Capybara::Session selenium_safari #refresh it reposts/
67
+ skip "Safari opens an alert that can't be closed"
68
+ when 'Capybara::Session selenium_safari node #double_click should allow to adjust the offset',
69
+ 'Capybara::Session selenium_safari node #double_click should double click an element'
70
+ pending "safardriver doesn't generate a double click event"
71
+ when 'Capybara::Session selenium_safari node #click should allow multiple modifiers',
72
+ /Capybara::Session selenium_safari node #(click|right_click|double_click) should allow modifiers/
73
+ pending "safaridriver doesn't take key state into account when clicking"
74
+ when 'Capybara::Session selenium_safari #fill_in on a pre-populated textfield with a reformatting onchange should trigger change when clearing field'
75
+ pending "safardriver clear doesn't generate change event"
76
+ when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
77
+ 'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
78
+ skip 'safaridriver loses the ability to find elements in the document after `go_back`'
79
+ when 'Capybara::Session selenium_safari node #send_keys should hold modifiers at top level'
80
+ skip 'Need to look into this'
81
+ end
82
+ end
83
+
84
+ RSpec.describe 'Capybara::Session with safari' do
85
+ include Capybara::SpecHelper
86
+ include_examples 'Capybara::Session', TestSessions::Safari, SAFARI_DRIVER
87
+ include_examples Capybara::RSpecMatchers, TestSessions::Safari, SAFARI_DRIVER
88
+
89
+ context 'storage' do
90
+ describe '#reset!' do
91
+ it 'clears storage by default' do
92
+ session = TestSessions::Safari
93
+ session.visit('/with_js')
94
+ session.find(:css, '#set-storage').click
95
+ session.reset!
96
+ session.visit('/with_js')
97
+ expect(session.evaluate_script('Object.keys(localStorage)')).to be_empty
98
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).to be_empty
99
+ end
100
+
101
+ it 'does not clear storage when false' do
102
+ skip "Safari webdriver doesn't support multiple sessions"
103
+ session = Capybara::Session.new(:selenium_safari_not_clear_storage, TestApp)
104
+ session.visit('/with_js')
105
+ session.find(:css, '#set-storage').click
106
+ session.reset!
107
+ session.visit('/with_js')
108
+ expect(session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
109
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'timeout' do
115
+ it 'sets the http client read timeout' do
116
+ expect(TestSessions::Safari.driver.browser.send(:bridge).http.read_timeout).to eq 30
117
+ end
118
+ end
119
+
120
+ describe 'filling in Safari-specific date and time fields with keystrokes' do
121
+ let(:datetime) { Time.new(1983, 6, 19, 6, 30) }
122
+ let(:session) { TestSessions::Safari }
123
+
124
+ before do
125
+ skip 'Too many other things broken currently'
126
+ session.visit('/form')
127
+ end
128
+
129
+ it 'should fill in a date input with a String' do
130
+ session.fill_in('form_date', with: '06/19/1983')
131
+ session.click_button('awesome')
132
+ expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
133
+ end
134
+
135
+ it 'should fill in a time input with a String' do
136
+ session.fill_in('form_time', with: '06:30A')
137
+ session.click_button('awesome')
138
+ results = extract_results(session)['time']
139
+ expect(Time.parse(results).strftime('%r')).to eq datetime.strftime('%r')
140
+ end
141
+
142
+ it 'should fill in a datetime input with a String' do
143
+ session.fill_in('form_datetime', with: "06/19/1983\t06:30A")
144
+ session.click_button('awesome')
145
+ expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
146
+ end
147
+ end
148
+ end
@@ -4,17 +4,17 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Server do
6
6
  it 'should spool up a rack server' do
7
- @app = proc { |_env| [200, {}, ['Hello Server!']] }
8
- @server = Capybara::Server.new(@app).boot
7
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
8
+ server = Capybara::Server.new(app).boot
9
9
 
10
- @res = Net::HTTP.start(@server.host, @server.port) { |http| http.get('/') }
10
+ res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
11
11
 
12
- expect(@res.body).to include('Hello Server')
12
+ expect(res.body).to include('Hello Server')
13
13
  end
14
14
 
15
15
  it 'should do nothing when no server given' do
16
16
  expect do
17
- @server = Capybara::Server.new(nil).boot
17
+ Capybara::Server.new(nil).boot
18
18
  end.not_to raise_error
19
19
  end
20
20
 
@@ -42,37 +42,36 @@ RSpec.describe Capybara::Server do
42
42
  it 'should use specified port' do
43
43
  Capybara.server_port = 22789
44
44
 
45
- @app = proc { |_env| [200, {}, ['Hello Server!']] }
46
- @server = Capybara::Server.new(@app).boot
45
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
46
+ server = Capybara::Server.new(app).boot
47
47
 
48
- @res = Net::HTTP.start(@server.host, 22789) { |http| http.get('/') }
49
- expect(@res.body).to include('Hello Server')
48
+ res = Net::HTTP.start(server.host, 22789) { |http| http.get('/') }
49
+ expect(res.body).to include('Hello Server')
50
50
 
51
51
  Capybara.server_port = nil
52
52
  end
53
53
 
54
54
  it 'should use given port' do
55
- @app = proc { |_env| [200, {}, ['Hello Server!']] }
56
- @server = Capybara::Server.new(@app, port: 22790).boot
55
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
56
+ server = Capybara::Server.new(app, port: 22790).boot
57
57
 
58
- @res = Net::HTTP.start(@server.host, 22790) { |http| http.get('/') }
59
- expect(@res.body).to include('Hello Server')
58
+ res = Net::HTTP.start(server.host, 22790) { |http| http.get('/') }
59
+ expect(res.body).to include('Hello Server')
60
60
 
61
61
  Capybara.server_port = nil
62
62
  end
63
63
 
64
64
  it 'should find an available port' do
65
- @app1 = proc { |_env| [200, {}, ['Hello Server!']] }
66
- @app2 = proc { |_env| [200, {}, ['Hello Second Server!']] }
67
-
68
- @server1 = Capybara::Server.new(@app1).boot
69
- @server2 = Capybara::Server.new(@app2).boot
70
-
71
- @res1 = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
72
- expect(@res1.body).to include('Hello Server')
65
+ responses = ['Hello Server!', 'Hello Second Server!']
66
+ apps = responses.map do |response|
67
+ proc { |_env| [200, {}, [response]] }
68
+ end
69
+ servers = apps.map { |app| Capybara::Server.new(app).boot }
73
70
 
74
- @res2 = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
75
- expect(@res2.body).to include('Hello Second Server')
71
+ servers.each_with_index do |server, idx|
72
+ result = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
73
+ expect(result.body).to include(responses[idx])
74
+ end
76
75
  end
77
76
 
78
77
  it 'should support SSL' do
@@ -98,28 +97,27 @@ RSpec.describe Capybara::Server do
98
97
  end
99
98
 
100
99
  context 'When Capybara.reuse_server is true' do
100
+ let!(:old_reuse_server) { Capybara.reuse_server }
101
+
101
102
  before do
102
- @old_reuse_server = Capybara.reuse_server
103
103
  Capybara.reuse_server = true
104
104
  end
105
105
 
106
106
  after do
107
- Capybara.reuse_server = @old_reuse_server
107
+ Capybara.reuse_server = old_reuse_server
108
108
  end
109
109
 
110
110
  it 'should use the existing server if it already running' do
111
- @app = proc { |_env| [200, {}, ['Hello Server!']] }
112
-
113
- @server1 = Capybara::Server.new(@app).boot
114
- @server2 = Capybara::Server.new(@app).boot
111
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
115
112
 
116
- res = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
117
- expect(res.body).to include('Hello Server')
113
+ servers = Array.new(2) { Capybara::Server.new(app).boot }
118
114
 
119
- res = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
120
- expect(res.body).to include('Hello Server')
115
+ servers.each do |server|
116
+ res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
117
+ expect(res.body).to include('Hello Server')
118
+ end
121
119
 
122
- expect(@server1.port).to eq(@server2.port)
120
+ expect(servers[0].port).to eq(servers[1].port)
123
121
  end
124
122
 
125
123
  it 'detects and waits for all reused server sessions pending requests' do
@@ -151,22 +149,20 @@ RSpec.describe Capybara::Server do
151
149
  end
152
150
 
153
151
  after do
154
- Capybara.reuse_server = @old_reuse_server
152
+ Capybara.reuse_server = @old_reuse_server # rubocop:disable RSpec/InstanceVariable
155
153
  end
156
154
 
157
155
  it 'should not reuse an already running server' do
158
- @app = proc { |_env| [200, {}, ['Hello Server!']] }
159
-
160
- @server1 = Capybara::Server.new(@app).boot
161
- @server2 = Capybara::Server.new(@app).boot
156
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
162
157
 
163
- res = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
164
- expect(res.body).to include('Hello Server')
158
+ servers = Array.new(2) { Capybara::Server.new(app).boot }
165
159
 
166
- res = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
167
- expect(res.body).to include('Hello Server')
160
+ servers.each do |server|
161
+ res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
162
+ expect(res.body).to include('Hello Server')
163
+ end
168
164
 
169
- expect(@server1.port).not_to eq(@server2.port)
165
+ expect(servers[0].port).not_to eq(servers[1].port)
170
166
  end
171
167
 
172
168
  it 'detects and waits for only one sessions pending requests' do
@@ -28,27 +28,28 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
28
28
  end
29
29
 
30
30
  describe 'exit codes' do
31
+ let(:env) { { 'SELENIUM_BROWSER' => session.driver.options[:browser].to_s } }
32
+ let!(:orig_dir) { Dir.getwd }
33
+
31
34
  before do
32
- @current_dir = Dir.getwd
33
35
  Dir.chdir(File.join(File.dirname(__FILE__), '..'))
34
- @env = { 'SELENIUM_BROWSER' => session.driver.options[:browser].to_s }
35
36
  end
36
37
 
37
38
  after do
38
- Dir.chdir(@current_dir)
39
+ Dir.chdir(orig_dir)
39
40
  end
40
41
 
41
42
  it 'should have return code 1 when running selenium_driver_rspec_failure.rb' do
42
43
  skip 'only setup for local non-headless' if headless_or_remote?
43
44
 
44
- system(@env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
45
+ system(env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
45
46
  expect($CHILD_STATUS.exitstatus).to eq(1)
46
47
  end
47
48
 
48
49
  it 'should have return code 0 when running selenium_driver_rspec_success.rb' do
49
50
  skip 'only setup for local non-headless' if headless_or_remote?
50
51
 
51
- system(@env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
52
+ system(env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
52
53
  expect($CHILD_STATUS.exitstatus).to eq(0)
53
54
  end
54
55
  end
@@ -71,6 +72,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
71
72
 
72
73
  context '#fill_in_with empty string and no options' do
73
74
  it 'should trigger change when clearing a field' do
75
+ pending "safaridriver doesn't trigger change for clear" if safari?(session)
74
76
  session.visit('/with_js')
75
77
  session.fill_in('with_change_event', with: '')
76
78
  # click outside the field to trigger the change event
@@ -115,6 +117,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
115
117
 
116
118
  it 'should only trigger onchange once' do
117
119
  session.visit('/with_js')
120
+ sleep 2 if safari?(session) # Safari needs a delay (to load event handlers maybe ???)
118
121
  session.fill_in('with_change_event',
119
122
  with: 'some value',
120
123
  fill_options: { clear: :backspace })
@@ -139,13 +142,16 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
139
142
  with: '',
140
143
  fill_options: { clear: :backspace })
141
144
  # click outside the field to trigger the change event
142
- session.find(:css, 'body').click
145
+ # session.find(:css, 'body').click
146
+ session.find(:css, 'h1', text: 'FooBar').click
143
147
  expect(session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
144
148
  end
145
149
  end
146
150
 
147
151
  context '#fill_in with { clear: :none } fill_options' do
148
152
  it 'should append to content in a field' do
153
+ pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
154
+
149
155
  session.visit('/form')
150
156
  session.fill_in('form_first_name',
151
157
  with: 'Harry',
@@ -165,17 +171,20 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
165
171
  });
166
172
  JS
167
173
  # work around weird FF issue where it would create an extra focus issue in some cases
168
- session.find(:css, 'body').click
174
+ session.find(:css, 'h1', text: 'Form').click
175
+ # session.find(:css, 'body').click
169
176
  end
170
177
 
171
178
  it 'should generate standard events on changing value' do
172
179
  pending "IE 11 doesn't support date input type" if ie?(session)
180
+ pending "Safari doesn't support date input type" if safari?(session)
173
181
  session.fill_in('form_date', with: Date.today)
174
182
  expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
175
183
  end
176
184
 
177
185
  it 'should not generate input and change events if the value is not changed' do
178
186
  pending "IE 11 doesn't support date input type" if ie?(session)
187
+ pending "Safari doesn't support date input type" if safari?(session)
179
188
  session.fill_in('form_date', with: Date.today)
180
189
  session.fill_in('form_date', with: Date.today)
181
190
  # Chrome adds an extra focus for some reason - ok for now
@@ -263,6 +272,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
263
272
 
264
273
  describe '#evaluate_async_script' do
265
274
  it 'will timeout if the script takes too long' do
275
+ skip 'safaridriver returns the wrong error type' if safari?(session)
266
276
  session.visit('/with_js')
267
277
  expect do
268
278
  session.using_wait_time(1) do
@@ -297,6 +307,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
297
307
  before do
298
308
  skip "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, session)
299
309
  skip "IE doesn't support a DataTransfer constuctor" if ie?(session)
310
+ skip "Safari doesn't support" if safari?(session)
300
311
  end
301
312
 
302
313
  it 'should HTML5 drag and drop an object' do
@@ -349,10 +360,12 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
349
360
  pending "Selenium remote doesn't support transferring a directory" if remote?(session)
350
361
  pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && ENV['HEADLESS']
351
362
  pending "IE doesn't support uploading a directory" if ie?(session)
363
+ pending 'Chrome/chromedriver 73 breaks this' unless chrome_lt?(73, session)
364
+ pending "Safari doesn't support uploading a directory" if safari?(session)
352
365
 
353
366
  session.visit('/form')
354
- @test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
355
- session.attach_file('Directory Upload', @test_file_dir)
367
+ test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
368
+ session.attach_file('Directory Upload', test_file_dir)
356
369
  session.click_button('Upload Multiple')
357
370
  expect(session.body).to include('5 | ') # number of files
358
371
  end
@@ -366,19 +379,17 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
366
379
  end
367
380
  end
368
381
 
382
+ # rubocop:disable RSpec/InstanceVariable
369
383
  describe 'Capybara#disable_animation' do
370
384
  context 'when set to `true`' do
371
385
  before(:context) do # rubocop:disable RSpec/BeforeAfterAll
386
+ skip "Safari doesn't support multiple sessions" if safari?(session)
372
387
  # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
373
388
  # it doesn't affect any of these tests because the settings are applied per-session
374
389
  Capybara.disable_animation = true
375
390
  @animation_session = Capybara::Session.new(session.mode, TestApp.new)
376
391
  end
377
392
 
378
- after(:context) do # rubocop:disable RSpec/BeforeAfterAll
379
- @animation_session = nil
380
- end
381
-
382
393
  it 'should disable CSS transitions' do
383
394
  @animation_session.visit('with_animation')
384
395
  @animation_session.click_link('transition me away')
@@ -394,16 +405,13 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
394
405
 
395
406
  context 'if we pass in css that matches elements' do
396
407
  before(:context) do # rubocop:disable RSpec/BeforeAfterAll
408
+ skip "safaridriver doesn't support multiple sessions" if safari?(session)
397
409
  # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
398
410
  # it doesn't affect any of these tests because the settings are applied per-session
399
411
  Capybara.disable_animation = '#with_animation a'
400
412
  @animation_session_with_matching_css = Capybara::Session.new(session.mode, TestApp.new)
401
413
  end
402
414
 
403
- after(:context) do # rubocop:disable RSpec/BeforeAfterAll
404
- @animation_session_with_matching_css = nil
405
- end
406
-
407
415
  it 'should disable CSS transitions' do
408
416
  @animation_session_with_matching_css.visit('with_animation')
409
417
  @animation_session_with_matching_css.click_link('transition me away')
@@ -419,16 +427,13 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
419
427
 
420
428
  context 'if we pass in css that does not match elements' do
421
429
  before(:context) do # rubocop:disable RSpec/BeforeAfterAll
430
+ skip "Safari doesn't support multiple sessions" if safari?(session)
422
431
  # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
423
432
  # it doesn't affect any of these tests because the settings are applied per-session
424
433
  Capybara.disable_animation = '.this-class-matches-nothing'
425
434
  @animation_session_without_matching_css = Capybara::Session.new(session.mode, TestApp.new)
426
435
  end
427
436
 
428
- after(:context) do # rubocop:disable RSpec/BeforeAfterAll
429
- @animation_session_without_matching_css = nil
430
- end
431
-
432
437
  it 'should not disable CSS transitions' do
433
438
  @animation_session_without_matching_css.visit('with_animation')
434
439
  @animation_session_without_matching_css.click_link('transition me away')
@@ -446,6 +451,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
446
451
  end
447
452
  end
448
453
  end
454
+ # rubocop:enable RSpec/InstanceVariable
449
455
 
450
456
  describe ':element selector' do
451
457
  it 'can find html5 svg elements' do