Path: blob/trunk/rb/lib/selenium/webdriver/firefox/profile.rb
1865 views
# frozen_string_literal: true12# Licensed to the Software Freedom Conservancy (SFC) under one3# or more contributor license agreements. See the NOTICE file4# distributed with this work for additional information5# regarding copyright ownership. The SFC licenses this file6# to you under the Apache License, Version 2.0 (the7# "License"); you may not use this file except in compliance8# with the License. You may obtain a copy of the License at9#10# http://www.apache.org/licenses/LICENSE-2.011#12# Unless required by applicable law or agreed to in writing,13# software distributed under the License is distributed on an14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY15# KIND, either express or implied. See the License for the16# specific language governing permissions and limitations17# under the License.1819module Selenium20module WebDriver21module Firefox22class Profile23include ProfileHelper2425VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze26WEBDRIVER_PREFS = {27port: 'webdriver_firefox_port',28log_file: 'webdriver.log.file'29}.freeze3031DEFAULT_PREFERENCES = {32'browser.newtabpage.enabled' => false,33'browser.startup.homepage' => 'about:blank',34'browser.usedOnWindows10.introURL' => 'about:blank',35'network.captive-portal-service.enabled' => false,36'security.csp.enable' => false37}.freeze3839LOCK_FILES = %w[.parentlock parent.lock lock].freeze4041attr_reader :name, :log_file42attr_writer :secure_ssl, :load_no_focus_lib4344class << self45def ini46@ini ||= ProfilesIni.new47end4849def from_name(name)50profile = ini[name]51return profile if profile5253raise Error::WebDriverError, "unable to find profile named: #{name.inspect}"54end5556def decoded(json)57JSON.parse(json)58end59end6061#62# Create a new Profile instance63#64# @example User configured profile65#66# profile = Selenium::WebDriver::Firefox::Profile.new67# profile['network.proxy.http'] = 'localhost'68# profile['network.proxy.http_port'] = 909069#70# driver = Selenium::WebDriver.for :firefox, :profile => profile71#7273def initialize(model = nil)74@model = verify_model(model)7576@additional_prefs = read_model_prefs77@extensions = {}78end7980def layout_on_disk81profile_dir = @model ? create_tmp_copy(@model) : Dir.mktmpdir('webdriver-profile')82FileReaper << profile_dir8384install_extensions(profile_dir)85delete_lock_files(profile_dir)86delete_extensions_cache(profile_dir)87update_user_prefs_in(profile_dir)8889profile_dir90end9192#93# Set a preference for this particular profile.94#95# @see http://kb.mozillazine.org/About:config_entries96# @see http://preferential.mozdev.org/preferences.html97#9899def []=(key, value)100unless VALID_PREFERENCE_TYPES.any? { |e| value.is_a? e }101raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"102end103104if value.is_a?(String) && Util.stringified?(value)105raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"106end107108@additional_prefs[key.to_s] = value109end110111def port=(port)112self[WEBDRIVER_PREFS[:port]] = port113end114115def log_file=(file)116@log_file = file117self[WEBDRIVER_PREFS[:log_file]] = file118end119120#121# Add the extension (directory, .zip or .xpi) at the given path to the profile.122#123124def add_extension(path, name = extension_name_for(path))125@extensions[name] = Extension.new(path)126end127128def proxy=(proxy)129raise TypeError, "expected #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}" unless proxy.is_a? Proxy130131case proxy.type132when :manual133self['network.proxy.type'] = 1134135set_manual_proxy_preference 'ftp', proxy.ftp136set_manual_proxy_preference 'http', proxy.http137set_manual_proxy_preference 'ssl', proxy.ssl138set_manual_proxy_preference 'socks', proxy.socks139140self['network.proxy.no_proxies_on'] = proxy.no_proxy || ''141when :pac142self['network.proxy.type'] = 2143self['network.proxy.autoconfig_url'] = proxy.pac144when :auto_detect145self['network.proxy.type'] = 4146else147raise ArgumentError, "unsupported proxy type #{proxy.type}"148end149end150151alias as_json encoded152153private154155def set_manual_proxy_preference(key, value)156return unless value157158host, port = value.to_s.split(':', 2)159160self["network.proxy.#{key}"] = host161self["network.proxy.#{key}_port"] = Integer(port) if port162end163164def install_extensions(directory)165destination = File.join(directory, 'extensions')166167@extensions.each do |name, extension|168WebDriver.logger.debug({extension: name}.inspect, id: :firefox_profile)169extension.write_to(destination)170end171end172173def read_model_prefs174return {} unless @model175176read_user_prefs(File.join(@model, 'user.js'))177end178179def delete_extensions_cache(directory)180FileUtils.rm_f File.join(directory, 'extensions.cache')181end182183def delete_lock_files(directory)184LOCK_FILES.each do |name|185FileUtils.rm_f File.join(directory, name)186end187end188189def extension_name_for(path)190File.basename(path, File.extname(path))191end192193def update_user_prefs_in(directory)194path = File.join(directory, 'user.js')195prefs = read_user_prefs(path)196prefs.merge! self.class::DEFAULT_PREFERENCES197prefs.merge!(@additional_prefs)198199# If the user sets the home page, we should also start up there200prefs['startup.homepage_welcome_url'] ||= prefs['browser.startup.homepage']201202write_prefs prefs, path203end204205def read_user_prefs(path)206prefs = {}207return prefs unless File.exist?(path)208209File.read(path).split("\n").each do |line|210next unless line =~ /user_pref\("([^"]+)"\s*,\s*(.+?)\);/211212key = Regexp.last_match(1)&.strip213value = Regexp.last_match(2)&.strip214215# wrap the value in an array to make it a valid JSON string.216prefs[key] = JSON.parse("[#{value}]").first217end218219prefs220end221222def write_prefs(prefs, path)223File.open(path, 'w') do |file|224prefs.each do |key, value|225file.puts %{user_pref("#{key}", #{value.to_json});}226end227end228end229end230231# Profile232end # Firefox233end # WebDriver234end # Selenium235236237