# encoding: utf-8## 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_EXTENSION_PATH=File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/webdriver.xpi")WEBDRIVER_PREFS={native_events: 'webdriver_enable_native_events',untrusted_certs: 'webdriver_accept_untrusted_certs',untrusted_issuer: 'webdriver_assume_untrusted_issuer',port: 'webdriver_firefox_port',log_file: 'webdriver.log.file'}.freezeattr_reader:name,:log_fileattr_writer:secure_ssl,:native_events,:load_no_focus_libclass<<selfdefini@ini||=ProfilesIni.newenddeffrom_name(name)profile=ini[name]returnprofileifprofileraiseError::WebDriverError,"unable to find profile named: #{name.inspect}"enddefdefault_preferences@default_preferences||=JSON.parse(File.read(File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/prefs.json"))).freezeendend## 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)model_prefs=read_model_prefsifmodel_prefs.empty?@native_events=DEFAULT_ENABLE_NATIVE_EVENTS@secure_ssl=DEFAULT_SECURE_SSL@untrusted_issuer=DEFAULT_ASSUME_UNTRUSTED_ISSUER@load_no_focus_lib=DEFAULT_LOAD_NO_FOCUS_LIB@additional_prefs={}else# TODO: clean this up@native_events=model_prefs.delete(WEBDRIVER_PREFS[:native_events])=='true'@secure_ssl=model_prefs.delete(WEBDRIVER_PREFS[:untrusted_certs])!='true'@untrusted_issuer=model_prefs.delete(WEBDRIVER_PREFS[:untrusted_issuer])=='true'# not stored in profile atm, so will always be false.@load_no_focus_lib=model_prefs.delete(WEBDRIVER_PREFS[:load_no_focus_lib])=='true'@additional_prefs=model_prefsend@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]]=fileenddefadd_webdriver_extensionreturnif@extensions.key?(:webdriver)add_extension(WEBDRIVER_EXTENSION_PATH,:webdriver)end## 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)enddefnative_events?@native_events==trueenddefload_no_focus_lib?@load_no_focus_lib==trueenddefsecure_ssl?@secure_ssl==trueenddefassume_untrusted_certificate_issuer?@untrusted_issuer==trueenddefassume_untrusted_certificate_issuer=(bool)@untrusted_issuer=boolenddefproxy=(proxy)unlessproxy.is_a?ProxyraiseTypeError,"expected #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}"endcaseproxy.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']=ifproxy.no_proxyproxy.no_proxyelse''endwhen:pacself['network.proxy.type']=2self['network.proxy.autoconfig_url']=proxy.pacwhen:auto_detectself['network.proxy.type']=4elseraiseArgumentError,"unsupported proxy type #{proxy.type}"endproxyenddefencodedZipper.zip(layout_on_disk)endprivatedefset_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({extenstion: name}.inspect)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)%w[.parentlock parent.lock].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_preferences.fetch'mutable'prefs.merge!@additional_prefsprefs.merge!self.class.default_preferences.fetch'frozen'prefs[WEBDRIVER_PREFS[:untrusted_certs]]=!secure_ssl?prefs[WEBDRIVER_PREFS[:native_events]]=native_events?prefs[WEBDRIVER_PREFS[:untrusted_issuer]]=assume_untrusted_certificate_issuer?# 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