# 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.moduleSeleniummoduleWebDrivermoduleFirefoxclassProfileincludeProfileHelperVALID_PREFERENCE_TYPES=[TrueClass,FalseClass,Integer,Float,String].freezeWEBDRIVER_PREFS={port: 'webdriver_firefox_port',log_file: 'webdriver.log.file'}.freezeDEFAULT_PREFERENCES={'browser.newtabpage.enabled'=>false,'browser.startup.homepage'=>'about:blank','browser.usedOnWindows10.introURL'=>'about:blank','network.captive-portal-service.enabled'=>false,'security.csp.enable'=>false}.freezeLOCK_FILES=%w[.parentlock parent.lock lock].freezeattr_reader:name,:log_fileattr_writer:secure_ssl,:load_no_focus_libclass<<selfdefini@ini||=ProfilesIni.newenddeffrom_name(name)profile=ini[name]returnprofileifprofileraiseError::WebDriverError,"unable to find profile named: #{name.inspect}"enddefdecoded(json)JSON.parse(json)endend## Create a new Profile instance## @example User configured profile## profile = Selenium::WebDriver::Firefox::Profile.new# profile['network.proxy.http'] = 'localhost'# profile['network.proxy.http_port'] = 9090## driver = Selenium::WebDriver.for :firefox, :profile => profile#definitialize(model=nil)@model=verify_model(model)@additional_prefs=read_model_prefs@extensions={}enddeflayout_on_diskprofile_dir=@model?create_tmp_copy(@model):Dir.mktmpdir('webdriver-profile')FileReaper<<profile_dirinstall_extensions(profile_dir)delete_lock_files(profile_dir)delete_extensions_cache(profile_dir)update_user_prefs_in(profile_dir)profile_dirend## Set a preference for this particular profile.## @see http://kb.mozillazine.org/About:config_entries# @see http://preferential.mozdev.org/preferences.html#def[]=(key,value)unlessVALID_PREFERENCE_TYPES.any?{|e|value.is_a?e}raiseTypeError,"expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"endifvalue.is_a?(String)&&Util.stringified?(value)raiseArgumentError,"preference values must be plain strings: #{key.inspect} => #{value.inspect}"end@additional_prefs[key.to_s]=valueenddefport=(port)self[WEBDRIVER_PREFS[:port]]=portenddeflog_file=(file)@log_file=fileself[WEBDRIVER_PREFS[:log_file]]=fileend## Add the extension (directory, .zip or .xpi) at the given path to the profile.#defadd_extension(path,name=extension_name_for(path))@extensions[name]=Extension.new(path)enddefproxy=(proxy)raiseTypeError,"expected #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}"unlessproxy.is_a?Proxycaseproxy.typewhen:manualself['network.proxy.type']=1set_manual_proxy_preference'ftp',proxy.ftpset_manual_proxy_preference'http',proxy.httpset_manual_proxy_preference'ssl',proxy.sslset_manual_proxy_preference'socks',proxy.socksself['network.proxy.no_proxies_on']=proxy.no_proxy||''when:pacself['network.proxy.type']=2self['network.proxy.autoconfig_url']=proxy.pacwhen:auto_detectself['network.proxy.type']=4elseraiseArgumentError,"unsupported proxy type #{proxy.type}"endendaliasas_jsonencodedprivatedefset_manual_proxy_preference(key,value)returnunlessvaluehost,port=value.to_s.split(':',2)self["network.proxy.#{key}"]=hostself["network.proxy.#{key}_port"]=Integer(port)ifportenddefinstall_extensions(directory)destination=File.join(directory,'extensions')@extensions.eachdo|name,extension|WebDriver.logger.debug({extension: name}.inspect,id: :firefox_profile)extension.write_to(destination)endenddefread_model_prefsreturn{}unless@modelread_user_prefs(File.join(@model,'user.js'))enddefdelete_extensions_cache(directory)FileUtils.rm_fFile.join(directory,'extensions.cache')enddefdelete_lock_files(directory)LOCK_FILES.eachdo|name|FileUtils.rm_fFile.join(directory,name)endenddefextension_name_for(path)File.basename(path,File.extname(path))enddefupdate_user_prefs_in(directory)path=File.join(directory,'user.js')prefs=read_user_prefs(path)prefs.merge!self.class::DEFAULT_PREFERENCESprefs.merge!(@additional_prefs)# If the user sets the home page, we should also start up thereprefs['startup.homepage_welcome_url']||=prefs['browser.startup.homepage']write_prefsprefs,pathenddefread_user_prefs(path)prefs={}returnprefsunlessFile.exist?(path)File.read(path).split("\n").eachdo|line|nextunlessline=~/user_pref\("([^"]+)"\s*,\s*(.+?)\);/key=Regexp.last_match(1)&.stripvalue=Regexp.last_match(2)&.strip# wrap the value in an array to make it a valid JSON string.prefs[key]=JSON.parse("[#{value}]").firstendprefsenddefwrite_prefs(prefs,path)File.open(path,'w')do|file|prefs.eachdo|key,value|file.puts%{user_pref("#{key}", #{value.to_json});}endendendend# Profileend# Firefoxend# WebDriverend# Selenium