module Support
  module Browser
    # Mixin containing methods for webdrivers that run remotely (such as Grid and Docker)
    module RemoteHelpers
      INSTANTIATION_TIMEOUT = 10
      # Sometimes BROWSER.close fails on remote drivers. This rescues it and posts an error message.
      def rescued_stop
        @instance.close
      rescue Selenium::WebDriver::Error::UnknownError, Selenium::WebDriver::Error::WebDriverError
        # Cannot communicate with the remote browser, so print to console and do nothing else:
        puts "[Support::Browser] Cannot communicate with browser"\
          " object: #{@instance}. Will just start a new one."
      end

      def instantiate_watir_browser
        browser = create_new_watir_browser

        # Setting this lambda fixes remote file upload
        # See https://github.com/watir/watir-webdriver/issues/175
        browser.driver.file_detector = lambda do |args|
          path = args.first
          path if File.exist?(path.to_s)
        end
        browser
      end

      def options
        caps = case @name
               when "chrome"
                 if ENV["CUCUMBER_PROFILE"] == "docker_compose"
                   OptionsDocker::CHROME_CAPABILITIES
                 else
                   Options::CHROME_CAPABILITIES
                 end
               when "firefox"
                 Support::Browser::Options::FirefoxProfile.new.as_caapbilities
               else
                 fail "Unknown browser! #{@name}"
               end
        caps[:url] = @url
        caps[:read_timeout] = 180
        caps
      end

      private

      def create_new_watir_browser
        max_tries = 5
        retry_message = proc do
          puts "Failed to instantiate browser in #{INSTANTIATION_TIMEOUT} "\
          "seconds! Trying again..."
        end
        Retriable.retriable(
          on: Timeout::Error,
          on_retry: retry_message,
          tries: max_tries
        ) do
          Timeout.timeout(INSTANTIATION_TIMEOUT) do
            Watir::Browser.new @name.to_sym, options
          end
        end
      end
    end
  end
end
