module Watir class Capabilities attr_reader :options def initialize(browser, options = {}) @options = options.dup Watir.logger.info "Creating Browser instance of #{browser} with user provided options: #{@options.inspect}" @browser = if browser == :remote && @options.key?(:browser) @options.delete(:browser) elsif browser == :remote && @options.key?(:desired_capabilities) @options[:desired_capabilities].browser_name.to_sym else browser.to_sym end @selenium_browser = browser == :remote || options[:url] ? :remote : browser @selenium_opts = {} end def to_args [@selenium_browser, process_arguments] end private def process_arguments url = @options.delete(:url) @selenium_opts[:url] = url if url create_http_client @selenium_opts[:port] = @options.delete(:port) if @options.key?(:port) @selenium_opts[:driver_opts] = @options.delete(:driver_opts) if @options.key?(:driver_opts) @selenium_opts[:listener] = @options.delete(:listener) if @options.key?(:listener) process_browser_options process_capabilities Watir.logger.info "Creating Browser instance with Watir processed options: #{@selenium_opts.inspect}" @selenium_opts end def create_http_client client_timeout = @options.delete(:client_timeout) open_timeout = @options.delete(:open_timeout) read_timeout = @options.delete(:read_timeout) http_client = @options.delete(:http_client) %i[open_timeout read_timeout client_timeout].each do |t| next if http_client.nil? || !respond_to?(t) msg = "You can pass #{t} value directly into Watir::Browser opt without needing to use :http_client" Watir.logger.warn msg, ids: %i[http_client use_capabilities] end http_client ||= Selenium::WebDriver::Remote::Http::Default.new http_client.timeout = client_timeout if client_timeout http_client.open_timeout = open_timeout if open_timeout http_client.read_timeout = read_timeout if read_timeout @selenium_opts[:http_client] = http_client end # TODO: - this will get addressed with Capabilities Update # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/PerceivedComplexity: # rubocop:disable Metrics/CyclomaticComplexity:: def process_browser_options browser_options = @options.delete(:options) || {} case @selenium_browser when :chrome if @options.key?(:args) || @options.key?(:switches) browser_options ||= {} browser_options[:args] = (@options.delete(:args) || @options.delete(:switches)).dup end if @options.delete(:headless) browser_options ||= {} browser_options[:args] ||= [] browser_options[:args] += ['--headless', '--disable-gpu'] end @selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Chrome::Options @selenium_opts[:options] ||= Selenium::WebDriver::Chrome::Options.new(browser_options) when :firefox profile = @options.delete(:profile) if browser_options.is_a? Selenium::WebDriver::Firefox::Options @selenium_opts[:options] = browser_options if profile msg = 'Initializing Browser with both :profile and :option', ':profile as a key inside :option' Watir.logger.deprecate msg, ids: [:firefox_profile] end end if @options.delete(:headless) browser_options ||= {} browser_options[:args] ||= [] browser_options[:args] += ['--headless'] end @selenium_opts[:options] ||= Selenium::WebDriver::Firefox::Options.new(browser_options) @selenium_opts[:options].profile = profile if profile when :safari Selenium::WebDriver::Safari.technology_preview! if @options.delete(:technology_preview) when :remote if @browser == :chrome && @options.delete(:headless) args = @options.delete(:args) || @options.delete(:switches) || [] @options['chromeOptions'] = {'args' => args + ['--headless', '--disable-gpu']} end if @browser == :firefox && @options.delete(:headless) args = @options.delete(:args) || @options.delete(:switches) || [] @options[Selenium::WebDriver::Firefox::Options::KEY] = {'args' => args + ['--headless']} end if @browser == :safari && @options.delete(:technology_preview) @options['safari.options'] = {'technologyPreview' => true} end when :ie if @options.key?(:args) browser_options ||= {} browser_options[:args] = @options.delete(:args).dup end unless browser_options.is_a? Selenium::WebDriver::IE::Options ie_caps = browser_options.select { |k| Selenium::WebDriver::IE::Options::CAPABILITIES.include?(k) } browser_options = Selenium::WebDriver::IE::Options.new(browser_options) ie_caps.each { |k, v| browser_options.add_option(k, v) } end @selenium_opts[:options] = browser_options end end # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/PerceivedComplexity: # rubocop:enable Metrics/CyclomaticComplexity:: def process_capabilities caps = @options.delete(:desired_capabilities) if caps msg = 'You can pass values directly into Watir::Browser opt without needing to use :desired_capabilities' Watir.logger.warn msg, ids: [:use_capabilities] @selenium_opts.merge!(@options) else caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options end @selenium_opts[:desired_capabilities] = caps end end end