Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/rb/lib/selenium/webdriver/chromium/options.rb
1856 views
1
# frozen_string_literal: true
2
3
# Licensed to the Software Freedom Conservancy (SFC) under one
4
# or more contributor license agreements. See the NOTICE file
5
# distributed with this work for additional information
6
# regarding copyright ownership. The SFC licenses this file
7
# to you under the Apache License, Version 2.0 (the
8
# "License"); you may not use this file except in compliance
9
# with the License. You may obtain a copy of the License at
10
#
11
# http://www.apache.org/licenses/LICENSE-2.0
12
#
13
# Unless required by applicable law or agreed to in writing,
14
# software distributed under the License is distributed on an
15
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
# KIND, either express or implied. See the License for the
17
# specific language governing permissions and limitations
18
# under the License.
19
20
module Selenium
21
module WebDriver
22
module Chromium
23
class Options < WebDriver::Options
24
attr_accessor :profile, :logging_prefs
25
26
# see: http://chromedriver.chromium.org/capabilities
27
CAPABILITIES = {args: 'args',
28
binary: 'binary',
29
local_state: 'localState',
30
prefs: 'prefs',
31
detach: 'detach',
32
debugger_address: 'debuggerAddress',
33
exclude_switches: 'excludeSwitches',
34
minidump_path: 'minidumpPath',
35
emulation: 'mobileEmulation',
36
perf_logging_prefs: 'perfLoggingPrefs',
37
window_types: 'windowTypes',
38
android_package: 'androidPackage',
39
android_activity: 'androidActivity',
40
android_device_serial: 'androidDeviceSerial',
41
android_use_running_app: 'androidUseRunningApp'}.freeze
42
43
# NOTE: special handling of 'extensions' to validate when set instead of when used
44
attr_reader :extensions
45
46
# Create a new Options instance.
47
#
48
# @example
49
# options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
50
# driver = Selenium::WebDriver.for(:chrome, options: options)
51
#
52
# @param [Profile] profile An instance of a Chrome::Profile Class
53
# @param [Hash] opts the pre-defined options to create the Chrome::Options with
54
# @option opts [Array] encoded_extensions List of extensions that do not need to be Base64 encoded
55
# @option opts [Array<String>] args List of command-line arguments to use when starting Chrome
56
# @option opts [String] binary Path to the Chrome executable to use
57
# @option opts [Hash] prefs A hash with each entry consisting of the name of the preference and its value
58
# @option opts [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup
59
# @option opts [Hash] options A hash for raw options
60
# @option opts [Hash] emulation A hash for raw emulation options
61
# @option opts [Hash] local_state A hash for the Local State file in the user data folder
62
# @option opts [Boolean] detach whether browser is closed when the driver is sent the quit command
63
# @option opts [String] debugger_address address of a Chrome debugger server to connect to
64
# @option opts [Array<String>] exclude_switches command line switches to exclude
65
# @option opts [String] minidump_path Directory to store Chrome minidumps (linux only)
66
# @option opts [Hash] perf_logging_prefs A hash for performance logging preferences
67
# @option opts [Array<String>] window_types A list of window types to appear in the list of window handles
68
#
69
70
def initialize(profile: nil, **)
71
super(**)
72
73
@profile = profile
74
75
@options = {args: [],
76
prefs: {},
77
emulation: {},
78
extensions: [],
79
local_state: {},
80
exclude_switches: [],
81
perf_logging_prefs: {},
82
window_types: []}.merge(@options)
83
84
@logging_prefs = options.delete(:logging_prefs) || {}
85
@encoded_extensions = @options.delete(:encoded_extensions) || []
86
@extensions = []
87
@options.delete(:extensions).each { |ext| validate_extension(ext) }
88
end
89
90
#
91
# Add an extension by local path.
92
#
93
# @example
94
# options = Selenium::WebDriver::Chrome::Options.new
95
# options.add_extension('/path/to/extension.crx')
96
#
97
# @param [String] path The local path to the .crx file
98
#
99
100
def add_extension(path)
101
validate_extension(path)
102
end
103
104
#
105
# Add an extension by local path.
106
#
107
# @example
108
# extensions = ['/path/to/extension.crx', '/path/to/other.crx']
109
# options = Selenium::WebDriver::Chrome::Options.new
110
# options.extensions = extensions
111
#
112
# @param [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup
113
#
114
115
def extensions=(extensions)
116
extensions.each { |ext| validate_extension(ext) }
117
end
118
119
#
120
# Add an extension by Base64-encoded string.
121
#
122
# @example
123
# options = Selenium::WebDriver::Chrome::Options.new
124
# options.add_encoded_extension(encoded_string)
125
#
126
# @param [String] encoded The Base64-encoded string of the .crx file
127
#
128
129
def add_encoded_extension(encoded)
130
@encoded_extensions << encoded
131
end
132
133
#
134
# Add a command-line argument to use when starting Chrome.
135
#
136
# @example Start Chrome maximized
137
# options = Selenium::WebDriver::Chrome::Options.new
138
# options.add_argument('start-maximized')
139
#
140
# @param [String] arg The command-line argument to add
141
#
142
143
def add_argument(arg)
144
@options[:args] << arg
145
end
146
147
#
148
# Add a preference that is only applied to the user profile in use.
149
#
150
# @example Set the default homepage
151
# options = Selenium::WebDriver::Chrome::Options.new
152
# options.add_preference('homepage', 'http://www.seleniumhq.com/')
153
#
154
# @param [String] name Key of the preference
155
# @param [Boolean, String, Integer] value Value of the preference
156
#
157
158
def add_preference(name, value)
159
@options[:prefs][name] = value
160
end
161
162
#
163
# Add emulation device information
164
#
165
# see: http://chromedriver.chromium.org/mobile-emulation
166
#
167
# @example Start Chrome in mobile emulation mode by device name
168
# options = Selenium::WebDriver::Chrome::Options.new
169
# options.add_emulation(device_name: 'iPhone 6')
170
#
171
# @example Start Chrome in mobile emulation mode by device metrics
172
# options = Selenium::WebDriver::Chrome::Options.new
173
# options.add_emulation(device_metrics: {width: 400, height: 800, pixelRatio: 1, touch: true})
174
#
175
# @param [Hash] opts the pre-defined options for adding mobile emulation values
176
# @option opts [String] :device_name A valid device name from the Chrome DevTools Emulation panel
177
# @option opts [Hash] :device_metrics Hash containing width, height, pixelRatio, touch
178
# @option opts [String] :user_agent Full user agent
179
#
180
181
def add_emulation(**opts)
182
@options[:emulation] = opts
183
end
184
185
#
186
# Enables mobile browser use on Android.
187
#
188
# @see https://chromedriver.chromium.org/getting-started/getting-started---android
189
#
190
# @param [String] package The package name of the Chrome or WebView app.
191
# @param [String] serial_number The device serial number on which to launch the Chrome or WebView app.
192
# @param [String] use_running_app When true uses an already-running Chrome or WebView app,
193
# instead of launching the app with a clear data directory.
194
# @param [String] activity Name of the Activity hosting the WebView (Not available on Chrome Apps).
195
#
196
197
def enable_android(package: 'com.android.chrome', serial_number: nil, use_running_app: nil, activity: nil)
198
@options[:android_package] = package
199
@options[:android_activity] = activity unless activity.nil?
200
@options[:android_device_serial] = serial_number unless serial_number.nil?
201
@options[:android_use_running_app] = use_running_app unless use_running_app.nil?
202
end
203
204
protected
205
206
def process_browser_options(browser_options)
207
enable_logging(browser_options) unless @logging_prefs.empty?
208
209
options = browser_options[self.class::KEY]
210
options['binary'] ||= binary_path if binary_path
211
212
if @profile
213
options['args'] ||= []
214
options['args'] << "--user-data-dir=#{@profile.directory}"
215
end
216
217
return if (@encoded_extensions + @extensions).empty?
218
219
options['extensions'] = @encoded_extensions + @extensions.map { |ext| encode_extension(ext) }
220
end
221
222
def binary_path
223
Chrome.path
224
end
225
226
def encode_extension(path)
227
File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
228
end
229
230
def validate_extension(path)
231
raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
232
raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
233
234
@extensions << path
235
end
236
237
def camelize?(key)
238
!%w[localState prefs].include?(key)
239
end
240
end # Options
241
end # Chromium
242
end # WebDriver
243
end # Selenium
244
245