From 92d3eea9597e8ad610eea9e8a8c239e5548f343e Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 25 Jun 2018 16:31:31 -0700 Subject: [PATCH] Work around selenium lack of file_detector support with firefox/geckodriver --- .../selenium/nodes/marionette_node.rb | 24 ++++++++++++++++++- spec/selenium_spec_chrome_remote.rb | 9 +------ spec/selenium_spec_firefox_remote.rb | 2 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/capybara/selenium/nodes/marionette_node.rb b/lib/capybara/selenium/nodes/marionette_node.rb index 13b50b05..f726cceb 100644 --- a/lib/capybara/selenium/nodes/marionette_node.rb +++ b/lib/capybara/selenium/nodes/marionette_node.rb @@ -26,6 +26,28 @@ class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node def set_file(value) # rubocop:disable Naming/AccessorMethodName path_names = value.to_s.empty? ? [] : value native.clear - Array(path_names).each { |p| native.send_keys(p) } + Array(path_names).each do |path| + unless driver.browser.respond_to?(:upload) + if (fd = bridge.file_detector) + local_file = fd.call([path]) + path = upload(local_file) if local_file + end + end + native.send_keys(path) + end + end + +private + def bridge + driver.browser.send(:bridge) + end + + def upload(local_file) + unless File.file?(local_file) + raise Error::WebDriverError, "you may only upload files: #{local_file.inspect}" + end + + result = bridge.http.call(:post, "session/#{bridge.session_id}/file", {file: Selenium::WebDriver::Zipper.zip_file(local_file)}) + result['value'] end end diff --git a/spec/selenium_spec_chrome_remote.rb b/spec/selenium_spec_chrome_remote.rb index 3e3528fe..770c4d90 100644 --- a/spec/selenium_spec_chrome_remote.rb +++ b/spec/selenium_spec_chrome_remote.rb @@ -18,7 +18,7 @@ def ensure_selenium_running! rescue raise 'Selenium is not running. ' \ "You can run a selenium server easily with: \n" \ - ' $ docker-compose up -d selenium' + ' $ docker-compose up -d selenium_chrome' end Capybara.register_driver :selenium_chrome_remote do |app| @@ -40,18 +40,11 @@ module TestSessions end TestSessions::Chrome.driver.browser.file_detector = lambda do |args| - # args => ["/path/to/file"] - str = args.first.to_s - str if File.exist?(str) - end - -session.driver.browser.file_detector = lambda do |args| # args => ["/path/to/file"] str = args.first.to_s str if File.exist?(str) end - skipped_tests = %i[response_headers status_code trigger download] # skip window tests when headless for now - closing a window not supported by chromedriver/chrome skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS']) diff --git a/spec/selenium_spec_firefox_remote.rb b/spec/selenium_spec_firefox_remote.rb index dd3a8825..d5d5f7e1 100644 --- a/spec/selenium_spec_firefox_remote.rb +++ b/spec/selenium_spec_firefox_remote.rb @@ -18,7 +18,7 @@ def ensure_selenium_running! rescue raise 'Selenium is not running. ' \ "You can run a selenium server easily with: \n" \ - ' $ docker-compose up -d selenium' + ' $ docker-compose up -d selenium_firefox' end Capybara.register_driver :selenium_firefox_remote do |app|