# 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.moduleSeleniummoduleWebDrivermoduleChromiumclassOptions<WebDriver::Optionsattr_accessor:profile,:logging_prefs# see: http://chromedriver.chromium.org/capabilitiesCAPABILITIES={args: 'args',binary: 'binary',local_state: 'localState',prefs: 'prefs',detach: 'detach',debugger_address: 'debuggerAddress',exclude_switches: 'excludeSwitches',minidump_path: 'minidumpPath',emulation: 'mobileEmulation',perf_logging_prefs: 'perfLoggingPrefs',window_types: 'windowTypes',android_package: 'androidPackage',android_activity: 'androidActivity',android_device_serial: 'androidDeviceSerial',android_use_running_app: 'androidUseRunningApp'}.freeze# NOTE: special handling of 'extensions' to validate when set instead of when usedattr_reader:extensions# Create a new Options instance.## @example# options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])# driver = Selenium::WebDriver.for(:chrome, options: options)## @param [Profile] profile An instance of a Chrome::Profile Class# @param [Hash] opts the pre-defined options to create the Chrome::Options with# @option opts [Array] encoded_extensions List of extensions that do not need to be Base64 encoded# @option opts [Array<String>] args List of command-line arguments to use when starting Chrome# @option opts [String] binary Path to the Chrome executable to use# @option opts [Hash] prefs A hash with each entry consisting of the name of the preference and its value# @option opts [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup# @option opts [Hash] options A hash for raw options# @option opts [Hash] emulation A hash for raw emulation options# @option opts [Hash] local_state A hash for the Local State file in the user data folder# @option opts [Boolean] detach whether browser is closed when the driver is sent the quit command# @option opts [String] debugger_address address of a Chrome debugger server to connect to# @option opts [Array<String>] exclude_switches command line switches to exclude# @option opts [String] minidump_path Directory to store Chrome minidumps (linux only)# @option opts [Hash] perf_logging_prefs A hash for performance logging preferences# @option opts [Array<String>] window_types A list of window types to appear in the list of window handles#definitialize(profile: nil,**opts)super(**opts)@profile=profile@options={args: [],prefs: {},emulation: {},extensions: [],local_state: {},exclude_switches: [],perf_logging_prefs: {},window_types: []}.merge(@options)@logging_prefs=options.delete(:logging_prefs)||{}@encoded_extensions=@options.delete(:encoded_extensions)||[]@extensions=[]@options.delete(:extensions).each{|ext|validate_extension(ext)}end## Add an extension by local path.## @example# options = Selenium::WebDriver::Chrome::Options.new# options.add_extension('/path/to/extension.crx')## @param [String] path The local path to the .crx file#defadd_extension(path)validate_extension(path)end## Add an extension by local path.## @example# extensions = ['/path/to/extension.crx', '/path/to/other.crx']# options = Selenium::WebDriver::Chrome::Options.new# options.extensions = extensions## @param [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup#defextensions=(extensions)extensions.each{|ext|validate_extension(ext)}end## Add an extension by Base64-encoded string.## @example# options = Selenium::WebDriver::Chrome::Options.new# options.add_encoded_extension(encoded_string)## @param [String] encoded The Base64-encoded string of the .crx file#defadd_encoded_extension(encoded)@encoded_extensions<<encodedend## Add a command-line argument to use when starting Chrome.## @example Start Chrome maximized# options = Selenium::WebDriver::Chrome::Options.new# options.add_argument('start-maximized')## @param [String] arg The command-line argument to add#defadd_argument(arg)@options[:args]<<argend## Add a preference that is only applied to the user profile in use.## @example Set the default homepage# options = Selenium::WebDriver::Chrome::Options.new# options.add_preference('homepage', 'http://www.seleniumhq.com/')## @param [String] name Key of the preference# @param [Boolean, String, Integer] value Value of the preference#defadd_preference(name,value)@options[:prefs][name]=valueend## Add emulation device information## see: http://chromedriver.chromium.org/mobile-emulation## @example Start Chrome in mobile emulation mode by device name# options = Selenium::WebDriver::Chrome::Options.new# options.add_emulation(device_name: 'iPhone 6')## @example Start Chrome in mobile emulation mode by device metrics# options = Selenium::WebDriver::Chrome::Options.new# options.add_emulation(device_metrics: {width: 400, height: 800, pixelRatio: 1, touch: true})## @param [Hash] opts the pre-defined options for adding mobile emulation values# @option opts [String] :device_name A valid device name from the Chrome DevTools Emulation panel# @option opts [Hash] :device_metrics Hash containing width, height, pixelRatio, touch# @option opts [String] :user_agent Full user agent#defadd_emulation(**opts)@options[:emulation]=optsend## Enables mobile browser use on Android.## @see https://chromedriver.chromium.org/getting-started/getting-started---android## @param [String] package The package name of the Chrome or WebView app.# @param [String] serial_number The device serial number on which to launch the Chrome or WebView app.# @param [String] use_running_app When true uses an already-running Chrome or WebView app,# instead of launching the app with a clear data directory.# @param [String] activity Name of the Activity hosting the WebView (Not available on Chrome Apps).#defenable_android(package: 'com.android.chrome',serial_number: nil,use_running_app: nil,activity: nil)@options[:android_package]=package@options[:android_activity]=activityunlessactivity.nil?@options[:android_device_serial]=serial_numberunlessserial_number.nil?@options[:android_use_running_app]=use_running_appunlessuse_running_app.nil?endprotecteddefprocess_browser_options(browser_options)enable_logging(browser_options)unless@logging_prefs.empty?options=browser_options[self.class::KEY]options['binary']||=binary_pathifbinary_pathif@profileoptions['args']||=[]options['args']<<"--user-data-dir=#{@profile.directory}"endreturnif(@encoded_extensions+@extensions).empty?options['extensions']=@encoded_extensions+@extensions.map{|ext|encode_extension(ext)}enddefbinary_pathChrome.pathenddefencode_extension(path)File.open(path,'rb'){|crx_file|Base64.strict_encode64crx_file.read}enddefvalidate_extension(path)raiseError::WebDriverError,"could not find extension at #{path.inspect}"unlessFile.file?(path)raiseError::WebDriverError,"file was not an extension #{path.inspect}"unlessFile.extname(path)=='.crx'@extensions<<pathenddefcamelize?(key)!%w[localState prefs].include?(key)endend# Optionsend# Chromiumend# WebDriverend# Selenium