Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/rb/lib/selenium/webdriver/common/options.rb
1865 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
class Options
23
W3C_OPTIONS = %i[browser_name browser_version platform_name accept_insecure_certs page_load_strategy proxy
24
set_window_rect timeouts unhandled_prompt_behavior strict_file_interactability
25
web_socket_url].freeze
26
27
GRID_OPTIONS = %i[enable_downloads].freeze
28
29
class << self
30
attr_reader :driver_path
31
32
def chrome(**)
33
Chrome::Options.new(**)
34
end
35
36
def firefox(**)
37
Firefox::Options.new(**)
38
end
39
40
def ie(**)
41
IE::Options.new(**)
42
end
43
alias internet_explorer ie
44
45
def edge(**)
46
Edge::Options.new(**)
47
end
48
alias microsoftedge edge
49
50
def safari(**)
51
Safari::Options.new(**)
52
end
53
54
def set_capabilities
55
(W3C_OPTIONS + GRID_OPTIONS + self::CAPABILITIES.keys).each do |key|
56
next if method_defined? key
57
58
define_method key do
59
@options[key]
60
end
61
62
define_method :"#{key}=" do |value|
63
@options[key] = value
64
end
65
end
66
end
67
end
68
69
attr_accessor :options
70
71
def initialize(**opts)
72
self.class.set_capabilities
73
74
@options = opts
75
@options[:browser_name] = self.class::BROWSER
76
end
77
78
#
79
# Add a new option not yet handled by bindings.
80
#
81
# @example Leave Chrome open when chromedriver is killed
82
# options = Selenium::WebDriver::Chrome::Options.new
83
# options.add_option(:detach, true)
84
#
85
# @param [String, Symbol] name Name of the option
86
# @param [Boolean, String, Integer] value Value of the option
87
#
88
89
def add_option(name, value = nil)
90
name, value = name.first if value.nil? && name.is_a?(Hash)
91
@options[name] = value
92
end
93
94
def ==(other)
95
return false unless other.is_a? self.class
96
97
as_json == other.as_json
98
end
99
100
alias eql? ==
101
102
#
103
# @api private
104
#
105
106
def as_json(*)
107
options = @options.dup
108
109
downloads = options.delete(:enable_downloads)
110
options['se:downloadsEnabled'] = downloads unless downloads.nil?
111
w3c_options = process_w3c_options(options)
112
113
browser_options = self.class::CAPABILITIES.each_with_object({}) do |(capability_alias, capability_name), hash|
114
capability_value = options.delete(capability_alias)
115
hash[capability_name] = capability_value unless capability_value.nil?
116
end
117
118
raise Error::WebDriverError, "These options are not w3c compliant: #{options}" unless options.empty?
119
120
browser_options = {self.class::KEY => browser_options} if defined?(self.class::KEY)
121
122
process_browser_options(browser_options)
123
generate_as_json(w3c_options.merge(browser_options))
124
end
125
126
private
127
128
def w3c?(key)
129
W3C_OPTIONS.include?(key) || key.to_s.include?(':')
130
end
131
132
def process_w3c_options(options)
133
w3c_options = options.select { |key, val| w3c?(key) && !val.nil? }
134
w3c_options[:unhandled_prompt_behavior] &&= w3c_options[:unhandled_prompt_behavior]&.to_s&.tr('_', ' ')
135
options.delete_if { |key, _val| w3c?(key) }
136
w3c_options
137
end
138
139
def process_browser_options(_browser_options)
140
nil
141
end
142
143
def camelize?(_key)
144
true
145
end
146
147
def generate_as_json(value, camelize_keys: true)
148
if value.is_a?(Hash)
149
process_json_hash(value, camelize_keys)
150
elsif value.respond_to?(:as_json)
151
value.as_json
152
elsif value.is_a?(Array)
153
value.map { |val| generate_as_json(val, camelize_keys: camelize_keys) }
154
elsif value.is_a?(Symbol)
155
value.to_s
156
else
157
value
158
end
159
end
160
161
def process_json_hash(value, camelize_keys)
162
value.each_with_object({}) do |(key, val), hash|
163
next if val.respond_to?(:empty?) && val.empty?
164
165
camelize = camelize_keys ? camelize?(key) : false
166
key = convert_json_key(key, camelize: camelize)
167
hash[key] = generate_as_json(val, camelize_keys: camelize)
168
end
169
end
170
171
def convert_json_key(key, camelize: true)
172
key = key.to_s if key.is_a?(Symbol)
173
key = camel_case(key) if camelize
174
return key if key.is_a?(String)
175
176
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
177
end
178
179
def camel_case(str)
180
str.gsub(/_([a-z])/) { Regexp.last_match(1)&.upcase }
181
end
182
end # Options
183
end # WebDriver
184
end # Selenium
185
186