# frozen_string_literal: true# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.moduleSeleniummoduleWebDrivermoduleRemote## Specification of the desired and/or actual capabilities of the browser that the# server is being asked to create.#classCapabilitiesKNOWN=[:browser_name,:browser_version,:platform_name,:accept_insecure_certs,:page_load_strategy,:proxy,:set_window_rect,:timeouts,:unhandled_prompt_behavior,:strict_file_interactability,:web_socket_url,# remote-specific (webdriver.remote.sessionid):remote_session_id].freeze(KNOWN-%i[proxy timeouts]).eachdo|key|define_methodkeydo@capabilities[key]enddefine_method:"#{key}="do|value|@capabilities[key]=valueendend## Convenience methods for the common choices.#class<<selfdefalways_match(capabilities)new(always_match: capabilities)enddeffirst_match(*capabilities)new(first_match: capabilities)end## @api private#defjson_create(data)data=data.dupcaps=newprocess_timeouts(caps,data.delete('timeouts'))ifdata.key?('proxy')proxy=data.delete('proxy')caps.proxy=Proxy.json_create(proxy)unlessproxy.nil?||proxy.empty?end# Remote Server Specificifdata.key?('webdriver.remote.sessionid')caps[:remote_session_id]=data.delete('webdriver.remote.sessionid')endKNOWN.eachdo|cap|data_value=camel_case(cap)caps[cap]=data.delete(data_value)ifdata.key?(data_value)end# any remaining pairs will be added as is, with no conversioncaps.merge!(data)capsenddefcamel_case(str_or_sym)str_or_sym.to_s.gsub(/_([a-z])/){Regexp.last_match(1)&.upcase}endprivatedefprocess_timeouts(caps,timeouts)returniftimeouts.nil?caps.implicit_timeout=timeouts['implicit']caps.page_load_timeout=timeouts['pageLoad']caps.script_timeout=timeouts['script']endend## @param [Hash] opts# @option :browser_name [String] required browser name# @option :browser_version [String] required browser version number# @option :platform_name [Symbol] one of :any, :win, :mac, or :x# @option :accept_insecure_certs [Boolean] does the driver accept insecure SSL certifications?# @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration## @api public#definitialize(opts={})@capabilities={}self.proxy=opts.delete(:proxy)ifopts[:proxy]@capabilities.merge!(opts)end## Allows setting arbitrary capabilities.#def[]=(key,value)@capabilities[key]=valueenddef[](key)@capabilities[key]enddefmerge!(other)ifother.respond_to?(:capabilities,true)&&other.capabilities.is_a?(Hash)@capabilities.merge!other.capabilitieselsifother.is_a?Hash@capabilities.merge!otherelseraiseArgumentError,'argument should be a Hash or implement #capabilities'endenddefproxy@capabilities[:proxy]enddefproxy=(proxy)caseproxywhenHash@capabilities[:proxy]=Proxy.new(proxy)whenProxy,nil@capabilities[:proxy]=proxyelseraiseTypeError,"expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}"endenddeftimeouts@capabilities[:timeouts]||={}enddeftimeouts=(timeouts)@capabilities[:timeouts]=timeoutsenddefimplicit_timeouttimeouts[:implicit]enddefimplicit_timeout=(timeout)timeouts[:implicit]=timeoutenddefpage_load_timeouttimeouts[:page_load]||timeouts[:pageLoad]enddefpage_load_timeout=(timeout)timeouts[:page_load]=timeoutenddefscript_timeouttimeouts[:script]enddefscript_timeout=(timeout)timeouts[:script]=timeoutend## @api private#defas_json(*)@capabilities.each_with_object({})do|(key,value),hash|hash[convert_key(key)]=process_capabilities(key,value,hash)endenddefto_json(*)JSON.generateas_jsonenddef==(other)returnfalseunlessother.is_a?self.classas_json==other.as_jsonendaliaseql?==protectedattr_reader:capabilitiesprivatedefprocess_capabilities(key,value,hash)casevaluewhenArrayvalue.map{|v|process_capabilities(key,v,hash)}whenHashvalue.each_with_object({})do|(k,v),h|h[convert_key(k)]=process_capabilities(k,v,h)endwhenCapabilities,Optionsvalue.as_jsonelseconvert_value(key,value)endenddefconvert_key(key)casekeywhenStringkey.to_swhenSymbolself.class.camel_case(key)elseraiseTypeError,"expected String or Symbol, got #{key.inspect}:#{key.class}"endenddefconvert_value(key,value)casekeywhen:platformvalue.to_s.upcasewhen:proxyvalue&.as_jsonwhen:unhandled_prompt_behaviorvalue.is_a?(Symbol)?value.to_s.tr('_',' '):valueelsevalueendendend# Capabilitiesend# Remoteend# WebDriverend# Selenium