diff --git a/lib/capybara/selenium/nodes/marionette_node.rb b/lib/capybara/selenium/nodes/marionette_node.rb index 2d29b5cf..31727e66 100644 --- a/lib/capybara/selenium/nodes/marionette_node.rb +++ b/lib/capybara/selenium/nodes/marionette_node.rb @@ -26,8 +26,10 @@ class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node end def set_file(value) # rubocop:disable Naming/AccessorMethodName + native.clear # By default files are appended so we have to clear here + return super if driver.browser.capabilities[:browser_version].to_f >= 62.0 + path_names = value.to_s.empty? ? [] : value - native.clear Array(path_names).each do |path| unless driver.browser.respond_to?(:upload) if (fd = bridge.file_detector) diff --git a/lib/capybara/spec/public/test.js b/lib/capybara/spec/public/test.js index df433545..7038bf5a 100644 --- a/lib/capybara/spec/public/test.js +++ b/lib/capybara/spec/public/test.js @@ -168,4 +168,7 @@ $(function() { sessionStorage.setItem('session', 'session_value'); localStorage.setItem('local', 'local value'); }) + $('#multiple-file').change(function(e){ + $('body').append($('

File input changed

')); + }) }); diff --git a/lib/capybara/spec/session/attach_file_spec.rb b/lib/capybara/spec/session/attach_file_spec.rb index 18e85132..6f2bf0a6 100644 --- a/lib/capybara/spec/session/attach_file_spec.rb +++ b/lib/capybara/spec/session/attach_file_spec.rb @@ -94,6 +94,21 @@ Capybara::SpecHelper.spec '#attach_file' do expect(@session.body).to include(File.read(@another_test_file_path)) expect(@session.body).not_to include(File.read(@test_file_path)) end + + it 'should fire change once when uploading multiple files from empty', requires: [:js] do + @session.visit('with_js') + @session.attach_file('multiple-file', + [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) }) + expect(@session).to have_css('.file_change', count: 1) + end + + it 'should fire change once for each set of files uploaded', requires: [:js] do + @session.visit('with_js') + @session.attach_file('multiple-file', [@test_jpg_file_path].map { |f| with_os_path_separators(f) }) + @session.attach_file('multiple-file', + [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) }) + expect(@session).to have_css('.file_change', count: 2) + end end context "with a locator that doesn't exist" do diff --git a/lib/capybara/spec/views/with_js.erb b/lib/capybara/spec/views/with_js.erb index 9ea68a7b..7ce86cfc 100644 --- a/lib/capybara/spec/views/with_js.erb +++ b/lib/capybara/spec/views/with_js.erb @@ -125,6 +125,10 @@

+

+ +

+

This is a draggable element.

diff --git a/spec/selenium_spec_chrome_remote.rb b/spec/selenium_spec_chrome_remote.rb index 4995e49a..ca1e714f 100644 --- a/spec/selenium_spec_chrome_remote.rb +++ b/spec/selenium_spec_chrome_remote.rb @@ -60,7 +60,9 @@ skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLE Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example| case example.metadata[:full_description] - when 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files' + when 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files', + 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded', + 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty' pending "Selenium with Remote Chrome doesn't support multiple file upload" end end diff --git a/spec/selenium_spec_firefox_remote.rb b/spec/selenium_spec_firefox_remote.rb index 900c76c5..d3a36a12 100644 --- a/spec/selenium_spec_firefox_remote.rb +++ b/spec/selenium_spec_firefox_remote.rb @@ -72,6 +72,9 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE skip 'Firefox insists on prompting without providing a way to suppress' when 'Capybara::Session selenium_firefox_remote #accept_prompt should accept the prompt with a blank response when there is a default' pending "Geckodriver doesn't set a blank response currently" + when 'Capybara::Session selenium_firefox_remote #attach_file with multipart form should fire change once for each set of files uploaded', + 'Capybara::Session selenium_firefox_remote #attach_file with multipart form should fire change once when uploading multiple files from empty' + pending 'Due to having to work around selenium remote lack of multiple file upload support the change event count is off' end end diff --git a/spec/selenium_spec_marionette.rb b/spec/selenium_spec_marionette.rb index 2991d310..4ad9bed6 100644 --- a/spec/selenium_spec_marionette.rb +++ b/spec/selenium_spec_marionette.rb @@ -62,6 +62,11 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, 'selenium', cap skip 'Firefox insists on prompting without providing a way to suppress' when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default' pending "Geckodriver doesn't set a blank response currently" + when 'Capybara::Session selenium #attach_file with multipart form should fire change once for each set of files uploaded' + pending 'Gekcodriver appends files so we have to first call clear for multiple files which creates an extra change ' \ + 'if files are already set' + when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty' + pending "FF < 62 doesn't support setting all files at once" if marionette_lt?(62, @session) end end