Skip to content

Commit 03d5b56

Browse files
committed
[rb] ensure options classes have defaults for accessors
1 parent 61cb525 commit 03d5b56

File tree

10 files changed

+120
-100
lines changed

10 files changed

+120
-100
lines changed

rb/.rubocop.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Metrics/ClassLength:
6262
- 'lib/selenium/webdriver/remote/capabilities.rb'
6363

6464
Metrics/CyclomaticComplexity:
65-
Max: 9
65+
Max: 10
6666
Exclude:
6767
- 'lib/selenium/webdriver/remote/capabilities.rb'
6868
- 'lib/selenium/webdriver/support/color.rb'
@@ -86,7 +86,7 @@ Metrics/ParameterLists:
8686

8787
# TODO: Refactor Chrome::Bridge#create_capabilities
8888
Metrics/PerceivedComplexity:
89-
Max: 9
89+
Max: 10
9090
Exclude:
9191
- 'lib/selenium/webdriver/remote/capabilities.rb'
9292

rb/lib/selenium/webdriver/chrome/options.rb

+17-32
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,6 @@ class Options < WebDriver::Options
4040
perf_logging_prefs: 'perfLoggingPrefs',
4141
window_types: 'windowTypes'}.freeze
4242

43-
CAPABILITIES.each_key do |key|
44-
define_method key do
45-
@options[key]
46-
end
47-
48-
define_method "#{key}=" do |value|
49-
@options[key] = value
50-
end
51-
end
52-
5343
# Create a new Options instance.
5444
#
5545
# @example
@@ -74,12 +64,21 @@ class Options < WebDriver::Options
7464
# @option opts [Array<String>] :window_types A list of window types to appear in the list of window handles
7565
#
7666

77-
def initialize(profile: nil, encoded_extensions: nil, **opts)
67+
def initialize(profile: nil, encoded_extensions: [], **opts)
7868
super(**opts)
7969

8070
@profile = profile
81-
@options[:encoded_extensions] = encoded_extensions if encoded_extensions
82-
@options[:extensions]&.each(&method(:validate_extension))
71+
@options[:encoded_extensions] = encoded_extensions
72+
73+
@options[:args] ||= []
74+
@options[:prefs] ||= {}
75+
@options[:emulation] ||= {}
76+
@options[:local_state] ||= {}
77+
@options[:exclude_switches] ||= []
78+
@options[:perf_logging_prefs] ||= {}
79+
@options[:window_types] ||= []
80+
@options[:extensions] ||= []
81+
@options[:extensions].each(&method(:validate_extension))
8382
end
8483

8584
#
@@ -94,7 +93,6 @@ def initialize(profile: nil, encoded_extensions: nil, **opts)
9493

9594
def add_extension(path)
9695
validate_extension(path)
97-
@options[:extensions] ||= []
9896
@options[:extensions] << path
9997
end
10098

@@ -109,7 +107,6 @@ def add_extension(path)
109107
#
110108

111109
def add_encoded_extension(encoded)
112-
@options[:encoded_extensions] ||= []
113110
@options[:encoded_extensions] << encoded
114111
end
115112
alias_method :encoded_extension=, :add_encoded_extension
@@ -125,7 +122,6 @@ def add_encoded_extension(encoded)
125122
#
126123

127124
def add_argument(arg)
128-
@options[:args] ||= []
129125
@options[:args] << arg
130126
end
131127

@@ -141,7 +137,6 @@ def add_argument(arg)
141137
#
142138

143139
def add_preference(name, value)
144-
@options[:prefs] ||= {}
145140
@options[:prefs][name] = value
146141
end
147142

@@ -185,16 +180,13 @@ def add_emulation(**opts)
185180
def process_browser_options(browser_options)
186181
options = browser_options[KEY]
187182
options['binary'] ||= binary_path if binary_path
188-
(options['args'] || []) << "--user-data-dir=#{@profile.directory}" if @profile
183+
options['args'] << "--user-data-dir=#{@profile.directory}" if @profile
189184
merge_extensions(options)
190185
end
191186

192187
def merge_extensions(browser_options)
193-
extensions = browser_options['extensions'] || []
194-
encoded_extensions = browser_options.delete(:encoded_extensions) || []
195-
196-
browser_options['extensions'] = extensions.map(&method(:encode_extension)) + encoded_extensions
197-
browser_options.delete('extensions') if browser_options['extensions'].empty?
188+
encoded_extensions = browser_options.delete(:encoded_extensions)
189+
browser_options[:extensions] = extensions.map(&method(:encode_extension)) + encoded_extensions
198190
end
199191

200192
def binary_path
@@ -210,15 +202,8 @@ def validate_extension(path)
210202
raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
211203
end
212204

213-
def generate_as_json(value, camelize_keys: true)
214-
if value.is_a?(Hash)
215-
value.each_with_object({}) do |(key, val), hash|
216-
key = convert_json_key(key, camelize: camelize_keys)
217-
hash[key] = generate_as_json(val, camelize_keys: key != 'prefs')
218-
end
219-
else
220-
super
221-
end
205+
def camelize?(key)
206+
!['prefs'].include?(key)
222207
end
223208
end # Options
224209
end # Chrome

rb/lib/selenium/webdriver/common/options.rb

+18-7
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,23 @@ class Options
2323
W3C_OPTIONS = %i[browser_name browser_version platform_name accept_insecure_certs page_load_strategy proxy
2424
set_window_rect timeouts unhandled_prompt_behavior strict_file_interactability].freeze
2525

26-
W3C_OPTIONS.each do |key|
27-
define_method key do
28-
@options[key]
29-
end
26+
def self.set_capabilities
27+
(W3C_OPTIONS + self::CAPABILITIES.keys).each do |key|
28+
define_method key do
29+
@options[key]
30+
end
3031

31-
define_method "#{key}=" do |value|
32-
@options[key] = value
32+
define_method "#{key}=" do |value|
33+
@options[key] = value
34+
end
3335
end
3436
end
3537

3638
attr_accessor :options
3739

3840
def initialize(options: nil, **opts)
41+
self.class.set_capabilities
42+
3943
@options = if options
4044
WebDriver.logger.deprecate(":options as keyword for initializing #{self.class}",
4145
"custom values directly in #new constructor",
@@ -84,10 +88,17 @@ def as_json(*)
8488

8589
private
8690

91+
def camelize?(_key)
92+
true
93+
end
94+
8795
def generate_as_json(value, camelize_keys: true)
8896
if value.is_a?(Hash)
8997
value.each_with_object({}) do |(key, val), hash|
90-
hash[convert_json_key(key, camelize: camelize_keys)] = generate_as_json(val, camelize_keys: camelize_keys)
98+
next if val.respond_to?(:empty?) && val.empty?
99+
100+
key = convert_json_key(key, camelize: camelize_keys)
101+
hash[key] = generate_as_json(val, camelize_keys: camelize?(key))
91102
end
92103
elsif value.respond_to?(:as_json)
93104
value.as_json

rb/lib/selenium/webdriver/edge_html/options.rb

+3-12
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ class Options < WebDriver::Options
2727
start_page: 'ms:startPage'}.freeze
2828
BROWSER = 'MicrosoftEdge'
2929

30-
CAPABILITIES.each_key do |key|
31-
define_method key do
32-
@options[key]
33-
end
34-
35-
define_method "#{key}=" do |value|
36-
@options[key] = value
37-
end
38-
end
39-
4030
#
4131
# Create a new Options instance for Edge.
4232
#
@@ -54,7 +44,9 @@ class Options < WebDriver::Options
5444

5545
def initialize(**opts)
5646
super(**opts)
57-
@options[:extensions]&.each(&method(:validate_extension))
47+
48+
@options[:extension_paths] ||= []
49+
@options[:extension_paths].each(&method(:validate_extension))
5850
end
5951

6052
#
@@ -69,7 +61,6 @@ def initialize(**opts)
6961

7062
def add_extension_path(path)
7163
validate_extension(path)
72-
@options[:extension_paths] ||= []
7364
@options[:extension_paths] << path
7465
end
7566

rb/lib/selenium/webdriver/firefox/options.rb

+8-14
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,13 @@ class Options < WebDriver::Options
2424
KEY = 'moz:firefoxOptions'
2525

2626
# see: https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html
27+
# NOTE: special handling of 'profile' to validate on construction instead of use
2728
CAPABILITIES = {binary: 'binary',
2829
args: 'args',
29-
profile: 'profile',
3030
log: 'log',
3131
prefs: 'prefs'}.freeze
3232
BROWSER = 'firefox'
3333

34-
CAPABILITIES.each_key do |key|
35-
define_method key do
36-
@options[key]
37-
end
38-
39-
define_method "#{key}=" do |value|
40-
@options[key] = value
41-
end
42-
end
43-
4434
#
4535
# Create a new Options instance, only for W3C-capable versions of Firefox.
4636
#
@@ -60,6 +50,8 @@ class Options < WebDriver::Options
6050
def initialize(log_level: nil, **opts)
6151
super(**opts)
6252

53+
@options[:args] ||= []
54+
@options[:prefs] ||= {}
6355
@options[:log] ||= {level: log_level} if log_level
6456
process_profile(@options[:profile]) if @options.key?(:profile)
6557
end
@@ -75,7 +67,6 @@ def initialize(log_level: nil, **opts)
7567
#
7668

7769
def add_argument(arg)
78-
@options[:args] ||= []
7970
@options[:args] << arg
8071
end
8172

@@ -91,7 +82,6 @@ def add_argument(arg)
9182
#
9283

9384
def add_preference(name, value)
94-
@options[:prefs] ||= {}
9585
@options[:prefs][name] = value
9686
end
9787

@@ -122,11 +112,14 @@ def headless!
122112
# @param [Profile, String] profile Profile to be used
123113
#
124114

125-
undef profile=
126115
def profile=(profile)
127116
process_profile(profile)
128117
end
129118

119+
def profile
120+
@options[:profile]
121+
end
122+
130123
def log_level
131124
@options.dig(:log, :level)
132125
end
@@ -140,6 +133,7 @@ def log_level=(level)
140133
def process_browser_options(browser_options)
141134
options = browser_options[KEY]
142135
options['binary'] ||= Firefox.path if Firefox.path
136+
options['profile'] = options.delete(:profile) if profile
143137
end
144138

145139
def process_profile(profile)

rb/lib/selenium/webdriver/ie/options.rb

-10
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,6 @@ class Options < WebDriver::Options
4343
}.freeze
4444
BROWSER = 'internet explorer'
4545

46-
CAPABILITIES.each_key do |key|
47-
define_method key do
48-
@options[key]
49-
end
50-
51-
define_method "#{key}=" do |value|
52-
@options[key] = value
53-
end
54-
end
55-
5646
attr_reader :args
5747

5848
#

rb/lib/selenium/webdriver/safari/options.rb

-9
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@ class Options < WebDriver::Options
2828
automatic_profiling: 'safari:automaticProfiling'}.freeze
2929
BROWSER = 'safari'
3030

31-
CAPABILITIES.each_key do |key|
32-
define_method key do
33-
@options[key]
34-
end
35-
36-
define_method "#{key}=" do |value|
37-
@options[key] = value
38-
end
39-
end
4031
end # Options
4132
end # Safari
4233
end # WebDriver

rb/spec/unit/selenium/webdriver/chrome/driver_spec.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,12 @@ def as_json(*)
210210

211211
it 'with Options instance with profile' do
212212
profile = Profile.new.tap(&:layout_on_disk)
213+
allow(profile).to receive(:directory).and_return("PROF_DIR")
213214
options = Options.new(profile: profile)
214-
expect_request(body: {capabilities: {firstMatch: [browserName: "chrome", 'goog:chromeOptions': {}]}})
215+
216+
expect_request(body: {capabilities:
217+
{firstMatch: [browserName: "chrome",
218+
'goog:chromeOptions': {"args": ["--user-data-dir=PROF_DIR"]}]}})
215219

216220
expect { Driver.new(capabilities: [options]) }.not_to raise_exception
217221
end

0 commit comments

Comments
 (0)