selenium-webdriver 4.49.0 → 4.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +20 -0
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/NOTICE +0 -0
- data/README.md +0 -0
- data/bin/linux-arm64/selenium-manager +0 -0
- data/bin/linux-x86_64/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/selenium-manager-THIRD-PARTY-NOTICES.txt +77 -46
- data/bin/selenium-manager.cdx.json +475 -475
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/server.rb +0 -0
- data/lib/selenium/webdriver/atoms/findElements.js +19 -4
- data/lib/selenium/webdriver/atoms/getAttribute.js +5 -2
- data/lib/selenium/webdriver/atoms/isDisplayed.js +5 -2
- data/lib/selenium/webdriver/atoms.rb +0 -0
- data/lib/selenium/webdriver/bidi/browser.rb +0 -0
- data/lib/selenium/webdriver/bidi/browsing_context.rb +0 -0
- data/lib/selenium/webdriver/bidi/error.rb +0 -0
- data/lib/selenium/webdriver/bidi/log_handler.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/cookies.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/credentials.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/headers.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/intercepted_auth.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/intercepted_item.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/intercepted_request.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/intercepted_response.rb +0 -0
- data/lib/selenium/webdriver/bidi/network/url_pattern.rb +0 -0
- data/lib/selenium/webdriver/bidi/network.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/bluetooth.rb +27 -23
- data/lib/selenium/webdriver/bidi/protocol/browser.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/browsing_context.rb +58 -4
- data/lib/selenium/webdriver/bidi/protocol/digital_credentials.rb +69 -0
- data/lib/selenium/webdriver/bidi/protocol/domain.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/emulation.rb +31 -0
- data/lib/selenium/webdriver/bidi/protocol/error_code.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/input.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/log.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/moz_debugging.rb +334 -0
- data/lib/selenium/webdriver/bidi/protocol/moz_profiler.rb +108 -0
- data/lib/selenium/webdriver/bidi/protocol/network.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/permissions.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/script.rb +1 -1
- data/lib/selenium/webdriver/bidi/protocol/session.rb +21 -20
- data/lib/selenium/webdriver/bidi/protocol/speculation.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/storage.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/user_agent_client_hints.rb +0 -0
- data/lib/selenium/webdriver/bidi/protocol/web_extension.rb +41 -5
- data/lib/selenium/webdriver/bidi/protocol.rb +3 -0
- data/lib/selenium/webdriver/bidi/serialization/record.rb +35 -2
- data/lib/selenium/webdriver/bidi/serialization/union.rb +0 -0
- data/lib/selenium/webdriver/bidi/serialization.rb +0 -0
- data/lib/selenium/webdriver/bidi/session.rb +0 -0
- data/lib/selenium/webdriver/bidi/struct.rb +0 -0
- data/lib/selenium/webdriver/bidi/support/bidi_generate.rb +178 -42
- data/lib/selenium/webdriver/bidi/support/check_generated.rb +0 -0
- data/lib/selenium/webdriver/bidi/transport.rb +0 -0
- data/lib/selenium/webdriver/bidi.rb +0 -0
- data/lib/selenium/webdriver/chrome/driver.rb +0 -0
- data/lib/selenium/webdriver/chrome/features.rb +0 -0
- data/lib/selenium/webdriver/chrome/options.rb +0 -0
- data/lib/selenium/webdriver/chrome/profile.rb +0 -0
- data/lib/selenium/webdriver/chrome/service.rb +0 -0
- data/lib/selenium/webdriver/chrome.rb +0 -0
- data/lib/selenium/webdriver/chromium/driver.rb +0 -0
- data/lib/selenium/webdriver/chromium/features.rb +0 -0
- data/lib/selenium/webdriver/chromium/options.rb +0 -0
- data/lib/selenium/webdriver/chromium/profile.rb +0 -0
- data/lib/selenium/webdriver/chromium.rb +0 -0
- data/lib/selenium/webdriver/common/action_builder.rb +0 -0
- data/lib/selenium/webdriver/common/alert.rb +0 -0
- data/lib/selenium/webdriver/common/child_process.rb +0 -0
- data/lib/selenium/webdriver/common/client_config.rb +0 -0
- data/lib/selenium/webdriver/common/driver.rb +24 -0
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +2 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_session_events.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/prints_page.rb +0 -0
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +0 -0
- data/lib/selenium/webdriver/common/driver_finder.rb +0 -0
- data/lib/selenium/webdriver/common/element.rb +0 -0
- data/lib/selenium/webdriver/common/error.rb +0 -0
- data/lib/selenium/webdriver/common/fedcm/account.rb +0 -0
- data/lib/selenium/webdriver/common/fedcm/dialog.rb +0 -0
- data/lib/selenium/webdriver/common/fedcm.rb +0 -0
- data/lib/selenium/webdriver/common/file_reaper.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/input_device.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/interaction.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/interactions.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/key_input.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/none_input.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pause.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/pointer_press.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/scroll.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +0 -0
- data/lib/selenium/webdriver/common/interactions/wheel_input.rb +0 -0
- data/lib/selenium/webdriver/common/keys.rb +0 -0
- data/lib/selenium/webdriver/common/local_driver.rb +0 -0
- data/lib/selenium/webdriver/common/log_entry.rb +0 -0
- data/lib/selenium/webdriver/common/logger.rb +0 -0
- data/lib/selenium/webdriver/common/logs.rb +0 -0
- data/lib/selenium/webdriver/common/manager.rb +0 -0
- data/lib/selenium/webdriver/common/navigation.rb +0 -0
- data/lib/selenium/webdriver/common/network.rb +0 -0
- data/lib/selenium/webdriver/common/options.rb +0 -0
- data/lib/selenium/webdriver/common/platform.rb +0 -0
- data/lib/selenium/webdriver/common/port_prober.rb +0 -0
- data/lib/selenium/webdriver/common/print_options.rb +0 -0
- data/lib/selenium/webdriver/common/profile_helper.rb +0 -0
- data/lib/selenium/webdriver/common/proxy.rb +0 -0
- data/lib/selenium/webdriver/common/script.rb +0 -0
- data/lib/selenium/webdriver/common/search_context.rb +0 -0
- data/lib/selenium/webdriver/common/selenium_manager.rb +0 -0
- data/lib/selenium/webdriver/common/service.rb +0 -0
- data/lib/selenium/webdriver/common/service_manager.rb +0 -0
- data/lib/selenium/webdriver/common/shadow_root.rb +0 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +0 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +0 -0
- data/lib/selenium/webdriver/common/takes_screenshot.rb +0 -0
- data/lib/selenium/webdriver/common/target_locator.rb +0 -0
- data/lib/selenium/webdriver/common/timeouts.rb +0 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +0 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +0 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +0 -0
- data/lib/selenium/webdriver/common/wait.rb +0 -0
- data/lib/selenium/webdriver/common/web_extension.rb +42 -0
- data/lib/selenium/webdriver/common/websocket_connection.rb +2 -2
- data/lib/selenium/webdriver/common/window.rb +0 -0
- data/lib/selenium/webdriver/common/zipper.rb +15 -11
- data/lib/selenium/webdriver/common.rb +1 -0
- data/lib/selenium/webdriver/devtools/console_event.rb +0 -0
- data/lib/selenium/webdriver/devtools/exception_event.rb +0 -0
- data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -0
- data/lib/selenium/webdriver/devtools/network_interceptor.rb +0 -0
- data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -0
- data/lib/selenium/webdriver/devtools/request.rb +0 -0
- data/lib/selenium/webdriver/devtools/response.rb +0 -0
- data/lib/selenium/webdriver/devtools.rb +0 -0
- data/lib/selenium/webdriver/edge/driver.rb +0 -0
- data/lib/selenium/webdriver/edge/features.rb +0 -0
- data/lib/selenium/webdriver/edge/options.rb +0 -0
- data/lib/selenium/webdriver/edge/profile.rb +0 -0
- data/lib/selenium/webdriver/edge/service.rb +0 -0
- data/lib/selenium/webdriver/edge.rb +0 -0
- data/lib/selenium/webdriver/firefox/driver.rb +0 -0
- data/lib/selenium/webdriver/firefox/features.rb +18 -7
- data/lib/selenium/webdriver/firefox/options.rb +0 -0
- data/lib/selenium/webdriver/firefox/profile.rb +0 -37
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +0 -0
- data/lib/selenium/webdriver/firefox/service.rb +0 -0
- data/lib/selenium/webdriver/firefox/util.rb +0 -0
- data/lib/selenium/webdriver/firefox.rb +0 -2
- data/lib/selenium/webdriver/ie/driver.rb +0 -0
- data/lib/selenium/webdriver/ie/features.rb +0 -0
- data/lib/selenium/webdriver/ie/options.rb +0 -0
- data/lib/selenium/webdriver/ie/service.rb +0 -0
- data/lib/selenium/webdriver/ie.rb +0 -0
- data/lib/selenium/webdriver/remote/bidi_bridge.rb +23 -0
- data/lib/selenium/webdriver/remote/bridge/commands.rb +0 -0
- data/lib/selenium/webdriver/remote/bridge/locator_converter.rb +0 -0
- data/lib/selenium/webdriver/remote/bridge.rb +20 -6
- data/lib/selenium/webdriver/remote/capabilities.rb +0 -0
- data/lib/selenium/webdriver/remote/driver.rb +0 -0
- data/lib/selenium/webdriver/remote/features.rb +9 -8
- data/lib/selenium/webdriver/remote/http/common.rb +0 -0
- data/lib/selenium/webdriver/remote/http/curb.rb +0 -0
- data/lib/selenium/webdriver/remote/http/default.rb +0 -0
- data/lib/selenium/webdriver/remote/response.rb +0 -0
- data/lib/selenium/webdriver/remote/server_error.rb +0 -0
- data/lib/selenium/webdriver/remote.rb +0 -0
- data/lib/selenium/webdriver/safari/driver.rb +0 -0
- data/lib/selenium/webdriver/safari/features.rb +0 -0
- data/lib/selenium/webdriver/safari/options.rb +0 -0
- data/lib/selenium/webdriver/safari/service.rb +0 -0
- data/lib/selenium/webdriver/safari.rb +0 -0
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +0 -0
- data/lib/selenium/webdriver/support/block_event_listener.rb +0 -0
- data/lib/selenium/webdriver/support/color.rb +0 -0
- data/lib/selenium/webdriver/support/escaper.rb +0 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +0 -0
- data/lib/selenium/webdriver/support/guards/guard.rb +0 -0
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +0 -0
- data/lib/selenium/webdriver/support/guards.rb +0 -0
- data/lib/selenium/webdriver/support/relative_locator.rb +0 -0
- data/lib/selenium/webdriver/support/select.rb +0 -0
- data/lib/selenium/webdriver/support.rb +0 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +0 -0
- data/lib/selenium-webdriver.rb +0 -0
- data/selenium-webdriver.gemspec +0 -1
- metadata +7 -27
- data/lib/selenium/webdriver/firefox/extension.rb +0 -103
|
@@ -30,7 +30,7 @@ module Selenium
|
|
|
30
30
|
class Record < ::Data
|
|
31
31
|
# Named Field, not Member, to avoid colliding with +::Data#members+.
|
|
32
32
|
Field = ::Data.define(:name, :wire_key, :nullable, :ref, :list, :fixed, :enum, :required, :primitive,
|
|
33
|
-
:scalar, :const)
|
|
33
|
+
:scalar, :const, :map)
|
|
34
34
|
|
|
35
35
|
def self.define(**spec)
|
|
36
36
|
extensible = spec.delete(:extensible) || false
|
|
@@ -61,7 +61,7 @@ module Selenium
|
|
|
61
61
|
nullable: meta[:nullable] || false, ref: meta[:ref],
|
|
62
62
|
list: meta[:list] || false, fixed: meta.fetch(:fixed, UNSET), enum: meta[:enum],
|
|
63
63
|
required: meta.fetch(:required, true), primitive: meta[:primitive],
|
|
64
|
-
scalar: meta[:scalar], const: meta.fetch(:const, UNSET))
|
|
64
|
+
scalar: meta[:scalar], const: meta.fetch(:const, UNSET), map: meta[:map])
|
|
65
65
|
end
|
|
66
66
|
private_class_method :field
|
|
67
67
|
|
|
@@ -127,6 +127,7 @@ module Selenium
|
|
|
127
127
|
validate_const(field, value)
|
|
128
128
|
check_outbound_shape(field, value)
|
|
129
129
|
check_outbound_primitive(field, value) unless field.list
|
|
130
|
+
check_outbound_map(field, value) if field.map
|
|
130
131
|
validate_ref(field, value) if field.ref
|
|
131
132
|
Serialization.validate!("#{name}##{field.name}", value, Protocol.const_get(field.enum)) if field.enum
|
|
132
133
|
end
|
|
@@ -210,6 +211,13 @@ module Selenium
|
|
|
210
211
|
raise ::ArgumentError, "#{name}##{field.name} expected #{field.primitive}, got #{value.inspect}"
|
|
211
212
|
end
|
|
212
213
|
|
|
214
|
+
# Outbound mirror of check_map: a map-typed arg must be a Hash whose values are the
|
|
215
|
+
# declared primitive, so a caller mistake is a local ArgumentError.
|
|
216
|
+
def check_outbound_map(field, value)
|
|
217
|
+
mismatch = map_mismatch(field, value)
|
|
218
|
+
raise ::ArgumentError, "#{name}##{field.name}#{mismatch}" if mismatch
|
|
219
|
+
end
|
|
220
|
+
|
|
213
221
|
def fixed?(field)
|
|
214
222
|
!UNSET.equal?(field.fixed)
|
|
215
223
|
end
|
|
@@ -236,6 +244,7 @@ module Selenium
|
|
|
236
244
|
|
|
237
245
|
if field.ref.nil?
|
|
238
246
|
return raw if field.list
|
|
247
|
+
return check_map(field, raw) if field.map
|
|
239
248
|
|
|
240
249
|
check_primitive(field, raw)
|
|
241
250
|
# A whole number is exact in both types, so the declared type is held with nothing lost.
|
|
@@ -285,6 +294,30 @@ module Selenium
|
|
|
285
294
|
raise Error::SerializationError, "#{name}##{field.name} expected #{field.primitive}, got #{raw.inspect}"
|
|
286
295
|
end
|
|
287
296
|
|
|
297
|
+
# A `map` field (`{*text => <primitive>}`, e.g. script.NodeProperties.attributes) must arrive
|
|
298
|
+
# as an object whose every value matches the declared primitive. Keys are JSON object keys,
|
|
299
|
+
# so they are strings by construction. The Hash passes through unchanged once validated.
|
|
300
|
+
def check_map(field, raw)
|
|
301
|
+
mismatch = map_mismatch(field, raw)
|
|
302
|
+
raise Error::SerializationError, "#{name}##{field.name}#{mismatch}" if mismatch
|
|
303
|
+
|
|
304
|
+
raw
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# The suffix of the error a map value earns, or nil when it conforms — shared by the inbound
|
|
308
|
+
# (SerializationError) and outbound (ArgumentError) checks so the two cannot drift apart. An
|
|
309
|
+
# unrecognized value primitive (none in PRIMITIVE_CHECKS) checks only the shape, matching the
|
|
310
|
+
# lenient default elsewhere.
|
|
311
|
+
def map_mismatch(field, value)
|
|
312
|
+
return " expected a map, got #{value.inspect}" unless value.is_a?(::Hash)
|
|
313
|
+
|
|
314
|
+
check = PRIMITIVE_CHECKS[field.map]
|
|
315
|
+
return if check.nil?
|
|
316
|
+
|
|
317
|
+
entry = value.find { |_, v| !check.call(v) }
|
|
318
|
+
"[#{entry[0].inspect}] expected #{field.map}, got #{entry[1].inspect}" if entry
|
|
319
|
+
end
|
|
320
|
+
|
|
288
321
|
def enum_hash(field)
|
|
289
322
|
(@enums ||= {})[field.name] ||= Protocol.const_get(field.enum)
|
|
290
323
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -48,8 +48,10 @@ module BiDiGenerate
|
|
|
48
48
|
RUBY_RESERVED = %w[begin end rescue ensure raise return yield if unless while until for do
|
|
49
49
|
case when then class module def].freeze
|
|
50
50
|
|
|
51
|
+
# A vendor namespace separator (`moz:debugging`) reads as a word boundary.
|
|
51
52
|
def self.camel_to_snake(str)
|
|
52
53
|
str
|
|
54
|
+
.tr(':', '_')
|
|
53
55
|
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
54
56
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
55
57
|
.downcase
|
|
@@ -72,6 +74,11 @@ module BiDiGenerate
|
|
|
72
74
|
"#{snake_to_class_name(camel_to_snake(domain))}::#{type_class_name(type_name)}"
|
|
73
75
|
end
|
|
74
76
|
|
|
77
|
+
# Source literal for a list of wire keys, in the form RuboCop expects at each size.
|
|
78
|
+
def self.word_array(words)
|
|
79
|
+
words.size > 1 ? "%w[#{words.join(' ')}]" : "[#{words.map { |w| "'#{w}'" }.join(', ')}]"
|
|
80
|
+
end
|
|
81
|
+
|
|
75
82
|
# Source literal for a discriminator/const value (string, boolean, or number).
|
|
76
83
|
def self.ruby_literal(value)
|
|
77
84
|
return 'nil' if value.nil?
|
|
@@ -100,15 +107,17 @@ module BiDiGenerate
|
|
|
100
107
|
RESERVED_FIELD_NAMES = (RUBY_RESERVED + %w[method hash class send dup clone freeze inspect
|
|
101
108
|
to_h to_s members with deconstruct deconstruct_keys
|
|
102
109
|
object_id tap itself then display
|
|
103
|
-
extensible
|
|
110
|
+
extensible]).freeze
|
|
104
111
|
|
|
105
112
|
# Append underscore to a field name that would shadow a core method; the wire
|
|
106
113
|
# name is unaffected, only the Ruby reader is renamed.
|
|
107
|
-
def self.safe_field_name(name)
|
|
114
|
+
def self.safe_field_name(name, extensible: true)
|
|
108
115
|
# A vendor-prefixed wire name carries a colon (moz:allowPrivateBrowsing); swap it
|
|
109
116
|
# for an underscore so the Ruby reader is a legal identifier. The wire key is kept.
|
|
110
117
|
name = name.tr(':', '_')
|
|
111
|
-
|
|
118
|
+
# Only an extensible record holds its undeclared fields in an `extensions` member.
|
|
119
|
+
reserved = RESERVED_FIELD_NAMES.include?(name) || (extensible && name == 'extensions')
|
|
120
|
+
reserved ? "#{name}_" : name
|
|
112
121
|
end
|
|
113
122
|
|
|
114
123
|
# SCREAMING_SNAKE constant name for an enum, matching the EVENTS map style
|
|
@@ -226,6 +235,20 @@ module BiDiGenerate
|
|
|
226
235
|
args << "result: #{result_ref}" if result_ref
|
|
227
236
|
BiDiGenerate.wrap_call('execute', args, indent)
|
|
228
237
|
end
|
|
238
|
+
|
|
239
|
+
# The full `def … end` block, shared by the module template and a vendor variant that adds
|
|
240
|
+
# the command (VendorModule#render), so both render a command identically.
|
|
241
|
+
def render_lines(indent)
|
|
242
|
+
pad = ' ' * indent
|
|
243
|
+
body = ' ' * (indent + 2)
|
|
244
|
+
lines = ["#{pad}# @api private", "#{pad}# @see #{BiDiGenerate::BIDI_DOC_URL}"]
|
|
245
|
+
lines << "#{pad}# @see #{spec_href}" if spec_href
|
|
246
|
+
lines << "#{pad}#{def_header(indent)}"
|
|
247
|
+
lines.concat(enum_checks(indent + 2).map { |check| "#{body}#{check}" })
|
|
248
|
+
assignment = params_assignment(indent + 2)
|
|
249
|
+
lines << "#{body}#{assignment}" if assignment
|
|
250
|
+
lines + ["#{body}#{execute_call(indent + 2)}", "#{pad}end"]
|
|
251
|
+
end
|
|
229
252
|
end
|
|
230
253
|
|
|
231
254
|
# A browser-specific extension to a command, kept out of the shared class so a
|
|
@@ -280,8 +303,9 @@ module BiDiGenerate
|
|
|
280
303
|
end
|
|
281
304
|
end
|
|
282
305
|
|
|
283
|
-
# A namespaced group of browser-specific
|
|
284
|
-
#
|
|
306
|
+
# A namespaced group of browser-specific commands (e.g. Firefox's), emitted as a subclass of
|
|
307
|
+
# the domain: it overrides the commands a vendor extends with `moz:` fields and adds the
|
|
308
|
+
# commands a vendor defines in the domain (`webExtension.moz:listExtensions`).
|
|
285
309
|
# A subclass (rather than a runtime-mixed module) keeps the vendor signatures statically
|
|
286
310
|
# visible to type checkers, and is constructed directly (`<Name>.new(source)`) for a
|
|
287
311
|
# matching session — no factory or runtime mix-in.
|
|
@@ -290,7 +314,7 @@ module BiDiGenerate
|
|
|
290
314
|
pad = ' ' * indent
|
|
291
315
|
lines = [
|
|
292
316
|
"#{pad}# @api private",
|
|
293
|
-
"#{pad}# #{namespace}: vendor variant of #{parent},
|
|
317
|
+
"#{pad}# #{namespace}: vendor variant of #{parent}, with browser-specific commands and params.",
|
|
294
318
|
"#{pad}# Construct #{name}.new(source) for a matching session; other sessions use #{parent}.",
|
|
295
319
|
"#{pad}class #{name} < #{parent}"
|
|
296
320
|
]
|
|
@@ -331,7 +355,7 @@ module BiDiGenerate
|
|
|
331
355
|
# for a scalar/opaque field); list wraps it in an array. wire_key is the exact
|
|
332
356
|
# JSON payload key (the schema's `wire` name, baked verbatim).
|
|
333
357
|
FieldIR = Struct.new(:ruby_name, :wire_key, :required, :nullable, :ref, :list, :enum, :primitive, :scalar, :const,
|
|
334
|
-
:rbs, keyword_init: true) do
|
|
358
|
+
:map_of, :rbs, keyword_init: true) do
|
|
335
359
|
# A `Serialization::Record.define` spec entry: `name: 'jsonKey'` shorthand, or
|
|
336
360
|
# `name: {wire_key:, …}` when the field carries JSON facts beyond its name.
|
|
337
361
|
# enum carries the allowed-values constant path, validated at construction.
|
|
@@ -351,11 +375,19 @@ module BiDiGenerate
|
|
|
351
375
|
facts << 'required: false' unless required
|
|
352
376
|
facts << 'nullable: true' if nullable
|
|
353
377
|
facts << "const: #{BiDiGenerate.ruby_literal(const)}" unless const.nil?
|
|
378
|
+
facts + type_facts
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# The facts describing the value's type and shape: what the runtime reads it as and checks
|
|
382
|
+
# it against. `map_of` is the value primitive of a string-keyed map (`{*text => text}`).
|
|
383
|
+
def type_facts
|
|
384
|
+
facts = []
|
|
354
385
|
facts << "ref: '#{ref}'" if ref
|
|
355
386
|
facts << 'list: true' if list
|
|
356
387
|
facts << "scalar: #{scalar_literal}" if scalar
|
|
357
388
|
facts << "enum: '#{enum}'" if enum
|
|
358
389
|
facts << "primitive: '#{primitive}'" if primitive
|
|
390
|
+
facts << "map: '#{map_of}'" if map_of
|
|
359
391
|
facts
|
|
360
392
|
end
|
|
361
393
|
|
|
@@ -543,15 +575,44 @@ module BiDiGenerate
|
|
|
543
575
|
:vendor_modules, :spec_href, keyword_init: true)
|
|
544
576
|
|
|
545
577
|
class Schema
|
|
578
|
+
# Vendor content (schema `vendor.<namespace>`) is folded in beside the spec's: a vendor
|
|
579
|
+
# module's commands and events become a domain of their own, and its types resolve like
|
|
580
|
+
# spec types and are emitted in that module (see owned_types).
|
|
546
581
|
def initialize(schema)
|
|
547
|
-
@types = schema['types']
|
|
548
|
-
@commands = schema['commands']
|
|
549
|
-
@events = schema['events']
|
|
550
|
-
@domains = schema['domains'] || {}
|
|
551
582
|
@vendor = schema['vendor'] || {}
|
|
583
|
+
@vendor_types = @vendor.values.map { |section| section['types'] || {} }.reduce({}, :merge)
|
|
584
|
+
@types = schema['types'].merge(@vendor_types)
|
|
585
|
+
@commands = schema['commands'] + vendor_messages('commands').select { |c| vendor_domain?(c['domain']) }
|
|
586
|
+
@events = schema['events'] + vendor_events
|
|
587
|
+
@domains = schema['domains'] || {}
|
|
552
588
|
promote_command_params_records!
|
|
553
589
|
end
|
|
554
590
|
|
|
591
|
+
# A vendor module's domain keeps its wire prefix (`moz:debugging`); a spec domain has none.
|
|
592
|
+
def vendor_domain?(domain) = domain.include?(':')
|
|
593
|
+
|
|
594
|
+
def vendor_messages(kind)
|
|
595
|
+
@vendor.values.flat_map { |section| section[kind] || [] }
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
# A vendor event in a spec domain would need the same vendor-variant routing as a command;
|
|
599
|
+
# none exists yet, so fail generation rather than leak it into the shared class.
|
|
600
|
+
def vendor_events
|
|
601
|
+
events = vendor_messages('events')
|
|
602
|
+
stray = events.reject { |e| vendor_domain?(e['domain']) }
|
|
603
|
+
raise "vendor event #{stray.first['method']} in spec domain #{stray.first['domain']} is unsupported" if stray.any?
|
|
604
|
+
|
|
605
|
+
events
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# The commands a vendor defines in a spec domain (`webExtension.moz:listExtensions`). They are
|
|
609
|
+
# emitted on that domain's vendor variant, never on the shared class (see vendor_modules_for).
|
|
610
|
+
def vendor_added_commands(domain, namespace)
|
|
611
|
+
return [] if vendor_domain?(domain)
|
|
612
|
+
|
|
613
|
+
(@vendor.dig(namespace, 'commands') || []).select { |c| c['domain'] == domain }
|
|
614
|
+
end
|
|
615
|
+
|
|
555
616
|
# The domain's `#module-<domain>` spec link, or nil when the schema has none.
|
|
556
617
|
def domain_href(domain)
|
|
557
618
|
@domains.dig(domain, 'specHref')
|
|
@@ -627,23 +688,36 @@ module BiDiGenerate
|
|
|
627
688
|
# any domain (or schema) with no vendor extensions, so non-vendor output is unaffected.
|
|
628
689
|
def vendor_modules_for(domain)
|
|
629
690
|
parent = BiDiGenerate.snake_to_class_name(BiDiGenerate.camel_to_snake(domain))
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
(spec['extends'] || {}).each do |type_name, entry|
|
|
691
|
+
@vendor.filter_map do |namespace, spec|
|
|
692
|
+
overrides = (spec['extends'] || {}).filter_map do |type_name, entry|
|
|
633
693
|
cmd = @commands.find { |c| c.dig('params', 'ref') == type_name }
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
groups[namespace] << build_vendor_command(cmd, type_name, entry, namespace)
|
|
694
|
+
build_vendor_command(cmd, type_name, entry, namespace) if cmd && cmd['domain'] == domain
|
|
637
695
|
end
|
|
638
|
-
|
|
639
|
-
|
|
696
|
+
added = vendor_added_commands(domain, namespace).map { |cmd| build_added_command(cmd, namespace, domain) }
|
|
697
|
+
commands = overrides + added
|
|
698
|
+
next if commands.empty?
|
|
699
|
+
|
|
640
700
|
VendorModule.new(name: BiDiGenerate.snake_to_class_name(namespace), namespace: namespace, parent: parent,
|
|
641
701
|
commands: commands)
|
|
642
702
|
end
|
|
643
703
|
end
|
|
644
704
|
|
|
705
|
+
# The vendor variant already scopes the command, so its name drops the namespace (`moz:listExtensions`
|
|
706
|
+
# → list_extensions); a name that would silently override a spec command fails generation instead.
|
|
707
|
+
def build_added_command(cmd, namespace, domain)
|
|
708
|
+
command = BiDiGenerate.build_command(self, cmd.merge('name' => cmd['name'].delete_prefix("#{namespace}:")))
|
|
709
|
+
spec_names = commands_for(domain).map do |c|
|
|
710
|
+
BiDiGenerate.safe_method_name(BiDiGenerate.camel_to_snake(c['name']))
|
|
711
|
+
end
|
|
712
|
+
if spec_names.include?(command.method_name)
|
|
713
|
+
raise "vendor command #{cmd['method']} would override spec command #{domain}.#{command.method_name}"
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
command
|
|
717
|
+
end
|
|
718
|
+
|
|
645
719
|
def build_vendor_command(cmd, type_name, entry, namespace)
|
|
646
|
-
shared = record_params(@types[type_name]['fields'])
|
|
720
|
+
shared = record_params(@types[type_name]['fields'], extensible_record?(type_name))
|
|
647
721
|
taken = shared.map(&:ruby_name)
|
|
648
722
|
VendorCommand.new(
|
|
649
723
|
method_name: BiDiGenerate.safe_method_name(BiDiGenerate.camel_to_snake(cmd['name'])),
|
|
@@ -692,23 +766,61 @@ module BiDiGenerate
|
|
|
692
766
|
return nil unless type
|
|
693
767
|
|
|
694
768
|
case type['kind']
|
|
695
|
-
when 'record' then record_params(type['fields'])
|
|
769
|
+
when 'record' then record_params(type['fields'], extensible_record?(params_ref['ref']))
|
|
696
770
|
when 'union' then union_params(type, params_ref['ref'])
|
|
697
771
|
end
|
|
698
772
|
end
|
|
699
773
|
|
|
700
774
|
# Enum types declared under "<domain>." become nested constant modules.
|
|
701
775
|
def enums_for(domain)
|
|
702
|
-
|
|
776
|
+
owned_types(domain).filter_map do |name, type|
|
|
703
777
|
next unless type['kind'] == 'enum'
|
|
704
|
-
next unless name.start_with?("#{domain}.")
|
|
705
778
|
|
|
706
779
|
pairs = type['values'].map { |v| [BiDiGenerate.enum_key(v), v] }
|
|
707
|
-
Enum.new(constant_name: BiDiGenerate.screaming_snake(name.
|
|
780
|
+
Enum.new(constant_name: BiDiGenerate.screaming_snake(name.split('.', 2).last), pairs: pairs,
|
|
708
781
|
primitive: type['primitive'], spec_href: type['specHref'])
|
|
709
782
|
end
|
|
710
783
|
end
|
|
711
784
|
|
|
785
|
+
# The types a domain's module declares. A spec domain's are the "<domain>." types the spec
|
|
786
|
+
# defines; a vendor's helper types under that prefix are not emitted until a generated
|
|
787
|
+
# command needs them. A vendor module (`moz:debugging`) owns the vendor types its commands
|
|
788
|
+
# and events name (Mozilla prefixes them `mozDebugging.`), read off their params and result refs.
|
|
789
|
+
def owned_types(domain)
|
|
790
|
+
vendor = vendor_domain?(domain)
|
|
791
|
+
prefixes = type_prefixes(domain).map { |prefix| "#{prefix}." }
|
|
792
|
+
added = vendor ? Set.new : vendor_types_reached(domain)
|
|
793
|
+
@types.select do |name, _|
|
|
794
|
+
next false unless prefixes.any? { |p| name.start_with?(p) }
|
|
795
|
+
|
|
796
|
+
@vendor_types.key?(name) ? vendor || added.include?(name) : !vendor
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
# The vendor types a vendor-added command in this spec domain reaches through its params and
|
|
801
|
+
# result, so they are emitted in the domain's module beside the command that returns them.
|
|
802
|
+
def vendor_types_reached(domain)
|
|
803
|
+
commands = @vendor.keys.flat_map { |namespace| vendor_added_commands(domain, namespace) }
|
|
804
|
+
pending = commands.flat_map { |c| [c.dig('params', 'ref'), c.dig('result', 'ref')] }.compact
|
|
805
|
+
reached = Set.new
|
|
806
|
+
until pending.empty?
|
|
807
|
+
name = pending.pop
|
|
808
|
+
next if reached.include?(name) || !@vendor_types.key?(name)
|
|
809
|
+
|
|
810
|
+
reached << name
|
|
811
|
+
pending.concat(plain_refs(@types[name]) + (@types[name]['variants'] || []))
|
|
812
|
+
end
|
|
813
|
+
reached
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
def type_prefixes(domain)
|
|
817
|
+
return [domain] unless vendor_domain?(domain)
|
|
818
|
+
|
|
819
|
+
messages = commands_for(domain) + events_for(domain)
|
|
820
|
+
refs = messages.flat_map { |m| [m.dig('params', 'ref'), m.dig('result', 'ref')] }
|
|
821
|
+
refs.compact.select { |ref| ref.include?('.') }.map { |ref| ref.split('.', 2).first }.uniq
|
|
822
|
+
end
|
|
823
|
+
|
|
712
824
|
# The protocol-root ErrorCode enum's wire values (e.g. "no such frame"), in schema order.
|
|
713
825
|
# Used to generate the BiDi-specific Error subclasses. [] when the schema has no ErrorCode.
|
|
714
826
|
def error_codes
|
|
@@ -721,10 +833,7 @@ module BiDiGenerate
|
|
|
721
833
|
# Command/event message envelopes (the `{method, params}` wire wrapper) are
|
|
722
834
|
# skipped — Transport forms that envelope, so nothing references them.
|
|
723
835
|
def types_for(domain)
|
|
724
|
-
|
|
725
|
-
@types.filter_map do |name, type|
|
|
726
|
-
next unless name.start_with?(prefix)
|
|
727
|
-
|
|
836
|
+
owned_types(domain).filter_map do |name, type|
|
|
728
837
|
case type['kind']
|
|
729
838
|
when 'record' then record_class(name, type) unless type['fields'].empty? || suppressed_record?(type)
|
|
730
839
|
when 'union' then union_class(name)
|
|
@@ -825,7 +934,7 @@ module BiDiGenerate
|
|
|
825
934
|
if node.key?('ref')
|
|
826
935
|
named = resolve_named(node['ref'])
|
|
827
936
|
return {ref: named[:ref], list: named[:list], nullable: nullable, scalar: named[:scalar],
|
|
828
|
-
rbs: nilable(named[:rbs], nullable)}
|
|
937
|
+
map: named[:map], rbs: nilable(named[:rbs], nullable)}
|
|
829
938
|
end
|
|
830
939
|
return resolve_union(node, nullable) if node.key?('union')
|
|
831
940
|
|
|
@@ -871,7 +980,7 @@ module BiDiGenerate
|
|
|
871
980
|
return OPAQUE unless type
|
|
872
981
|
|
|
873
982
|
case type['kind']
|
|
874
|
-
when 'record' then type['fields'].empty? ?
|
|
983
|
+
when 'record' then type['fields'].empty? ? map_record(type) : named_type(name)
|
|
875
984
|
when 'union' then named_union(name)
|
|
876
985
|
when 'enum' then {ref: nil, list: false, rbs: 'Symbol'}
|
|
877
986
|
when 'alias' then resolve_named_alias(name, type['type'], seen)
|
|
@@ -879,6 +988,18 @@ module BiDiGenerate
|
|
|
879
988
|
end
|
|
880
989
|
end
|
|
881
990
|
|
|
991
|
+
# A field-less record is either a genuinely empty one (EmptyParams, Extensible — opaque)
|
|
992
|
+
# or the projector's stand-in for an inline map (`{*text => text}` is hoisted to a record
|
|
993
|
+
# with no fields and the value type under `map`, e.g. script.NodePropertiesAttributes).
|
|
994
|
+
# A primitive-valued map becomes a `map` descriptor the runtime checks and a typed Hash;
|
|
995
|
+
# a ref- or union-valued one (the Mozilla vendor types) stays opaque for now.
|
|
996
|
+
def map_record(type)
|
|
997
|
+
primitive = type.dig('map', 'primitive')
|
|
998
|
+
return OPAQUE unless primitive && CHECKABLE_PRIMITIVES.include?(primitive)
|
|
999
|
+
|
|
1000
|
+
{ref: nil, list: false, map: primitive, rbs: "Hash[String, #{PRIMITIVE_RBS.fetch(primitive)}]"}
|
|
1001
|
+
end
|
|
1002
|
+
|
|
882
1003
|
# A named structured type's serialization ref (nil for a dotless/global type, never
|
|
883
1004
|
# emitted as a class) and its absolute RBS class path, derived independently so each
|
|
884
1005
|
# output keeps its own treatment of dotless names.
|
|
@@ -926,21 +1047,36 @@ module BiDiGenerate
|
|
|
926
1047
|
end
|
|
927
1048
|
|
|
928
1049
|
def record_class(name, type)
|
|
1050
|
+
extensible = extensible_record?(name)
|
|
929
1051
|
const = type['fields'].find { |f| baked_discriminator?(f) }
|
|
930
|
-
discriminator = const && {ruby_name:
|
|
1052
|
+
discriminator = const && {ruby_name: field_name(const, extensible),
|
|
931
1053
|
wire: const['wire'], value: const['type']['const'],
|
|
932
1054
|
rbs: rbs_const(const['type']['const'])}
|
|
933
|
-
fields = type['fields'].reject { |f| baked_discriminator?(f) }.map { |f| field_ir(f) }
|
|
1055
|
+
fields = type['fields'].reject { |f| baked_discriminator?(f) }.map { |f| field_ir(f, extensible) }
|
|
934
1056
|
# Every extensible type gets the extensions store: an undeclared wire key is preserved
|
|
935
1057
|
# and echoed back on any type the spec marks extensible, whether or not it is re-sendable.
|
|
936
|
-
# Extensibility alone is the signal; send-reachability does not enter into it.
|
|
1058
|
+
# Extensibility alone is the signal; send-reachability does not enter into it. A type a
|
|
1059
|
+
# vendor extends is open too: its vendor variant composes the vendor fields through that
|
|
1060
|
+
# store (see VendorCommand), which a closed record would reject.
|
|
937
1061
|
TypeClass.new(ruby_name: BiDiGenerate.type_class_name(name), fields: fields,
|
|
938
|
-
discriminator: discriminator, extensible:
|
|
1062
|
+
discriminator: discriminator, extensible: extensible,
|
|
939
1063
|
schema_name: name, synthetic: type['synthetic'] ? true : false,
|
|
940
1064
|
owner: type['owner'], label: type['label'], spec_href: type['specHref'],
|
|
941
1065
|
**directionality(name))
|
|
942
1066
|
end
|
|
943
1067
|
|
|
1068
|
+
def vendor_extended?(name)
|
|
1069
|
+
@vendor.values.any? { |spec| (spec['extends'] || {}).key?(name) }
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
def extensible_record?(name)
|
|
1073
|
+
@types.dig(name, 'extensible') || vendor_extended?(name) ? true : false
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
def field_name(field, extensible)
|
|
1077
|
+
BiDiGenerate.safe_field_name(BiDiGenerate.camel_to_snake(field['name']), extensible: extensible)
|
|
1078
|
+
end
|
|
1079
|
+
|
|
944
1080
|
# A const field is a baked discriminator tag, unless it is also nullable: the spec's
|
|
945
1081
|
# `literal | null` (browsingContext.setBypassCSP, emulation.setScriptingEnabled) is a
|
|
946
1082
|
# settable value (the literal to set, null to clear), so it stays a normal field that
|
|
@@ -949,14 +1085,14 @@ module BiDiGenerate
|
|
|
949
1085
|
field['type'].key?('const') && !field['type']['nullable']
|
|
950
1086
|
end
|
|
951
1087
|
|
|
952
|
-
def field_ir(field)
|
|
1088
|
+
def field_ir(field, extensible)
|
|
953
1089
|
resolved = resolve(field['type'])
|
|
954
|
-
ruby_name =
|
|
1090
|
+
ruby_name = field_name(field, extensible)
|
|
955
1091
|
FieldIR.new(ruby_name: ruby_name, wire_key: field['wire'],
|
|
956
1092
|
required: field['required'], nullable: resolved[:nullable],
|
|
957
1093
|
ref: resolved[:ref], list: resolved[:list], enum: enum_const(field['type']),
|
|
958
1094
|
primitive: leaf_primitive(field['type']), scalar: resolved[:scalar],
|
|
959
|
-
const: leaf_const(field['type']), rbs: resolved[:rbs])
|
|
1095
|
+
const: leaf_const(field['type']), map_of: resolved[:map], rbs: resolved[:rbs])
|
|
960
1096
|
end
|
|
961
1097
|
|
|
962
1098
|
# The literal value of a const field, following alias chains, so the runtime can reject a
|
|
@@ -1074,10 +1210,10 @@ module BiDiGenerate
|
|
|
1074
1210
|
scalar_values: spec['type']['scalarValues'], **directionality(name))
|
|
1075
1211
|
end
|
|
1076
1212
|
|
|
1077
|
-
def record_params(fields)
|
|
1213
|
+
def record_params(fields, extensible)
|
|
1078
1214
|
fields.map do |field|
|
|
1079
1215
|
Param.new(
|
|
1080
|
-
ruby_name:
|
|
1216
|
+
ruby_name: field_name(field, extensible),
|
|
1081
1217
|
wire_name: field['wire'],
|
|
1082
1218
|
required: field['required'],
|
|
1083
1219
|
enum: enum_const(field['type']),
|
|
@@ -1146,7 +1282,7 @@ module BiDiGenerate
|
|
|
1146
1282
|
|
|
1147
1283
|
selector = type['selector']
|
|
1148
1284
|
guard_union_dispatch_keys_simple!(selector, ref)
|
|
1149
|
-
params = merged_params(variants.map { |v| v['fields'] })
|
|
1285
|
+
params = merged_params(variants.map { |v| v['fields'] }, type['variants'].any? { |v| extensible_record?(v) })
|
|
1150
1286
|
annotate_discriminator_enum!(params, selector)
|
|
1151
1287
|
params
|
|
1152
1288
|
end
|
|
@@ -1180,12 +1316,12 @@ module BiDiGenerate
|
|
|
1180
1316
|
|
|
1181
1317
|
# Merge variant field lists into one flat param superset. A field is required only
|
|
1182
1318
|
# when every variant declares it required; variant-specific fields become optional.
|
|
1183
|
-
def merged_params(variant_fields)
|
|
1319
|
+
def merged_params(variant_fields, extensible)
|
|
1184
1320
|
all_fields = variant_fields.flatten
|
|
1185
1321
|
all_fields.map { |f| f['wire'] }.uniq.map do |wire|
|
|
1186
1322
|
field = all_fields.find { |f| f['wire'] == wire }
|
|
1187
1323
|
required = variant_fields.all? { |fields| fields.any? { |f| f['wire'] == wire && f['required'] } }
|
|
1188
|
-
Param.new(ruby_name:
|
|
1324
|
+
Param.new(ruby_name: field_name(field, extensible),
|
|
1189
1325
|
wire_name: wire, required: required, rbs: rbs_type(field['type']))
|
|
1190
1326
|
end
|
|
1191
1327
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -277,6 +277,30 @@ module Selenium
|
|
|
277
277
|
@network ||= WebDriver::Network.new(bridge)
|
|
278
278
|
end
|
|
279
279
|
|
|
280
|
+
#
|
|
281
|
+
# Installs a browser extension from an unpacked directory, a packed extension (.xpi/.crx/.zip),
|
|
282
|
+
# or base64-encoded bytes; works with remote (Grid) sessions.
|
|
283
|
+
#
|
|
284
|
+
# @note Chromium requires a BiDi session and installs only unpacked directories
|
|
285
|
+
# (SeleniumHQ/selenium#16541); Firefox falls back to the classic endpoint without BiDi.
|
|
286
|
+
# @param [String] path directory, packed extension, or base64-encoded bytes
|
|
287
|
+
# @return [WebExtension] the installed extension
|
|
288
|
+
#
|
|
289
|
+
|
|
290
|
+
def install_web_extension(...)
|
|
291
|
+
bridge.install_web_extension(...)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
#
|
|
295
|
+
# Uninstalls a browser extension installed with {#install_web_extension}.
|
|
296
|
+
#
|
|
297
|
+
# @param [WebExtension] extension the extension returned by {#install_web_extension}
|
|
298
|
+
#
|
|
299
|
+
|
|
300
|
+
def uninstall_web_extension(extension)
|
|
301
|
+
bridge.uninstall_web_extension(extension.id)
|
|
302
|
+
end
|
|
303
|
+
|
|
280
304
|
#-------------------------------- sugar --------------------------------
|
|
281
305
|
|
|
282
306
|
#
|
|
File without changes
|
|
File without changes
|
|
@@ -30,6 +30,7 @@ module Selenium
|
|
|
30
30
|
#
|
|
31
31
|
|
|
32
32
|
def install_addon(path, temporary = nil)
|
|
33
|
+
WebDriver.logger.deprecate('#install_addon', '#install_web_extension', id: :install_addon)
|
|
33
34
|
@bridge.install_addon(path, temporary)
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -40,6 +41,7 @@ module Selenium
|
|
|
40
41
|
#
|
|
41
42
|
|
|
42
43
|
def uninstall_addon(id)
|
|
44
|
+
WebDriver.logger.deprecate('#uninstall_addon', '#uninstall_web_extension', id: :uninstall_addon)
|
|
43
45
|
@bridge.uninstall_addon(id)
|
|
44
46
|
end
|
|
45
47
|
end # HasAddons
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|