Module: BiDiGenerate Private

Defined in:
rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb,
rb/lib/selenium/webdriver/bidi/support/check_generated.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Generates Ruby WebDriver BiDi protocol modules from the shared, binding-neutral BiDi schema produced by the JavaScript generator (see PR #17700):

//javascript/selenium-webdriver:create-bidi-src_schema -> bidi-schema.json

The schema is already normalized (inline enums hoisted, unions canonicalized, group composition flattened, wire names and nullability preserved verbatim), so this generator is a straight projection into Ruby with no CDDL interpretation.

Invoked via bazel run //rb/lib/selenium/webdriver:bidi-generate. Bazel passes the schema path (resolved through runfiles) plus the workspace-relative output directory as ARGV, and supplies the shared generated-note text as a runfile, so this is not runnable directly from a source checkout.

Defined Under Namespace

Classes: Accessor, Command, Enum, ErrorModule, Event, FieldIR, Module, Param, Schema, TypeClass, UnionClass, VariantIR, VendorCommand, VendorModule

Constant Summary collapse

BIDI_DOC_URL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Companion to the generated @api private tags: the page explaining why the BiDi implementation layer is internal and what higher-level API to use instead (see #17628).

'https://www.selenium.dev/documentation/warnings/bidi-implementation/'
LINE_LIMIT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

RuboCop's Layout/LineLength max; emitted Serialization::Record.define calls wrap to stay within it.

120
RUBY_RESERVED =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Ruby keywords that cannot be used as method names unquoted.

%w[begin end rescue ensure raise return yield if unless while until for do
case when then class module def].freeze
RESERVED_FIELD_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Object/Data methods a Data member name would shadow (breaking value semantics or reflection), e.g. a "method" field overriding Object#method.

(RUBY_RESERVED + %w[method hash class send dup clone freeze inspect
to_h to_s members with deconstruct deconstruct_keys
object_id tap itself then display
extensible]).freeze
RBS_VALUE_TYPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The RBS type a schema value primitive maps to; an unrecognized one is untyped.

{'string' => 'String', 'integer' => 'Integer', 'number' => 'Float',
'boolean' => 'bool'}.freeze
PARAMS_CLASS_KINDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Param kinds the named args can construct a Parameters object for (record fields, or a union dispatched to one of its variants); anything else forwards a raw hash.

%w[record union].freeze
INHERITED_INSTANCE_METHODS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Public instance methods every accessor would shadow if it reused their name: Domain's own (execute/initialize) plus everything Object/Kernel expose. The collision guard fails generation before a schema-driven shadow can ship.

(%w[execute initialize].to_set + Object.instance_methods.to_set(&:to_s)).freeze

Class Method Summary collapse

Class Method Details

.accessor?(type, wrappers, plainly_reached) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A type earns a send-side accessor when it is outbound and not a command param/result wrapper (a command method already builds those). A nested-away synthetic reached only as a union arm is excluded — it is built through its union (a variant factory or the command's flattened dispatch), never standalone. A top-level union variant record keeps its accessor (the plan constructs it directly, e.g. extension_path), as does a synthetic reached by a plain field ref (browsingContext.AccessibilityLocator's value).

Returns:

  • (Boolean)


1411
1412
1413
1414
1415
1416
1417
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1411

def self.accessor?(type, wrappers, plainly_reached)
  return false unless type.outbound
  return false if wrappers.include?(type.schema_name)

  nested_synthetic = !type.union? && type.synthetic
  !nested_synthetic || plainly_reached.include?(type.schema_name)
end

.bidi_only_classes(codes) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Class names among codes the classic Error module does not already define — the BiDi-only codes bidi/error.rb registers and whose RBS this file must declare. Shared codes already have RBS in common/error.rbs, so re-declaring them would duplicate the classic signatures. Only the RBS needs this split; the emitted map (error_code.rb) stays the full self-contained set.



1530
1531
1532
1533
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1530

def self.bidi_only_classes(codes)
  require_relative '../../common/error'
  codes.filter_map { |_wire, name| name unless ::Selenium::WebDriver::Error.const_defined?(name, false) }
end

.build_accessors(schema, domain, types) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Outbound-scoped domain accessors: for every emitted type a caller constructs to send, a prefix-free constructor on the Domain subclass. Built from the pre-nesting type list so a nested synthetic (referenced by a Ruby-relative Owner::Label path) is reachable.



1395
1396
1397
1398
1399
1400
1401
1402
1403
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1395

def self.build_accessors(schema, domain, types)
  wrappers = schema.command_wrapper_refs(domain)
  plainly_reached = schema.plainly_reached_types
  types.select { |t| accessor?(t, wrappers, plainly_reached) }.map do |t|
    Accessor.new(method_name: safe_method_name(camel_to_snake(type_class_name(t.schema_name))),
                 type_name: schema.domain_relative_path(t.schema_name), union: t.union?,
                 rbs_args: t.union? ? nil : t.rbs_new_args)
  end
end

.build_command(schema, cmd) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1442

def self.build_command(schema, cmd)
  params = schema.params_for(cmd['params'])
  # A param that can't flatten to a typed object (alias or non-record union) would be
  # silently dropped, so fail generation and handle that shape deliberately if it appears.
  if cmd['params'] && params.nil?
    raise "command #{cmd['method']} has params that cannot be expressed as a typed object"
  end

  params_ref = cmd['params'] && cmd['params']['ref']
  params_kind = schema.type_kind(params_ref)
  params_class = type_class_name(params_ref) if !params.empty? && PARAMS_CLASS_KINDS.include?(params_kind)
  Command.new(
    wire_name: cmd['method'],
    method_name: safe_method_name(camel_to_snake(cmd['name'])),
    params: params,
    result_ref: cmd['result'] && schema.structured_ref(cmd['result']['ref']),
    params_class: params_class,
    union_params: params_kind == 'union',
    spec_href: cmd['specHref']
  )
end

.build_event(schema, event) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1464
1465
1466
1467
1468
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1464

def self.build_event(schema, event)
  params = event['params']
  payload_ref = params && params['ref'] && schema.structured_ref(params['ref'])
  Event.new(wire_name: event['method'], event_name: camel_to_snake(event['name']), payload_ref: payload_ref)
end

.build_ir(schema) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1348

def self.build_ir(schema)
  schema.domains.map do |domain|
    types = schema.types_for(domain)
    thread_variant_arg_sigs(schema, types)
    vendor_modules = schema.vendor_modules_for(domain)
    mod = Module.new(
      name: domain,
      ruby_class: snake_to_class_name(camel_to_snake(domain)),
      filename: camel_to_snake(domain),
      commands: schema.commands_for(domain).map { |cmd| build_command(schema, cmd) },
      events: schema.events_for(domain).map { |ev| build_event(schema, ev) },
      enums: schema.enums_for(domain),
      accessors: build_accessors(schema, domain, types) + vendor_accessors(vendor_modules),
      types: nest_synthetic(types),
      vendor_modules: vendor_modules,
      spec_href: schema.domain_href(domain)
    )
    check_accessor_collisions!(mod)
    mod
  end
end

.call(schema_path, output_dir) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1492
1493
1494
1495
1496
1497
1498
1499
1500
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1492

def self.call(schema_path, output_dir)
  raw = load_json(schema_path)
  schema = Schema.new(raw)
  modules = build_ir(schema)

  emit(modules, output_dir, 'module.rb.erb', 'rb')
  emit(modules, sig_dir(output_dir), 'module.rbs.erb', 'rbs')
  emit_error_module(schema, output_dir)
end

.camel_to_snake(str) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A vendor namespace separator (moz:debugging) reads as a word boundary.



52
53
54
55
56
57
58
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 52

def self.camel_to_snake(str)
  str
    .tr(':', '_')
    .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
    .gsub(/([a-z\d])([A-Z])/, '\1_\2')
    .downcase
end

.check!(schema_rootpath) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Verifies the checked-in protocol .rb match what the generator would produce from the current schema — catching a hand-edit or a forgotten regeneration. Re-renders each module in memory (no file writes) and compares. The .rbs are covered by Steep.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 27

def self.check!(schema_rootpath)
  schema = Schema.new(JSON.parse(File.read(schema_path(schema_rootpath))))
  protocol_dir = File.expand_path('../protocol', __dir__)
  template = File.join(__dir__, 'templates', 'module.rb.erb')

  stale = build_ir(schema).filter_map do |mod|
    path = File.join(protocol_dir, "#{mod.filename}.rb")
    "#{mod.filename}.rb" unless File.exist?(path) && File.read(path) == render(mod, template)
  end
  stale << 'error_code.rb' unless error_module_current?(schema, protocol_dir)
  return if stale.empty?

  warn "Generated BiDi protocol code is stale or hand-edited: #{stale.sort.join(', ')}"
  warn 'Regenerate with: bazel run //rb/lib/selenium/webdriver:bidi-generate'
  exit 1
end

.check_accessor_collisions!(mod) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Fail generation if an accessor name would collide with a command method, an inherited method, or another accessor — turning a future shadow into a build error rather than a silently overridden method.



1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1427

def self.check_accessor_collisions!(mod)
  commands = mod.commands.to_set(&:method_name)
  seen = {}
  mod.accessors.each do |accessor|
    name = accessor.method_name
    clash = if commands.include?(name) then 'a command method'
            elsif INHERITED_INSTANCE_METHODS.include?(name) then 'an inherited method'
            elsif seen[name] then "the accessor for #{seen[name]}"
            end
    raise "accessor #{mod.ruby_class}##{name} collides with #{clash}" if clash

    seen[name] = accessor.type_name
  end
end

.emit(modules, output_dir, template, extension) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Renders every module through one template and writes the result into target, one file per module. Used for both the Ruby source and its RBS signatures.



1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1537

def self.emit(modules, output_dir, template, extension)
  target = File.join(workspace_root, output_dir)
  FileUtils.mkdir_p(target)

  tmpl = File.join(File.dirname(__FILE__), 'templates', template)
  modules.each do |mod|
    path = File.join(target, "#{mod.filename}.#{extension}")
    File.write(path, render(mod, tmpl))
    warn "bidi-generate: wrote #{path}"
  end
end

.emit_error_module(schema, output_dir) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Writes protocol/error_code.rb (+ its .rbs), the Protocol::ErrorCode map, into the same protocol dir as the generated domain files.



1519
1520
1521
1522
1523
1524
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1519

def self.emit_error_module(schema, output_dir)
  codes = error_code_map(schema)
  mod = ErrorModule.new(filename: 'error_code', codes: codes, new_classes: bidi_only_classes(codes))
  emit([mod], output_dir, 'error_code.rb.erb', 'rb')
  emit([mod], sig_dir(output_dir), 'error_code.rbs.erb', 'rbs')
end

.enum_const_path(type_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Domain-qualified path to an enum's frozen hash constant ("browsingContext.ReadinessState" → "BrowsingContext::READINESS_STATE"), so a generated command method can reference it for an outbound membership check.



141
142
143
144
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 141

def self.enum_const_path(type_name)
  domain, local = type_name.split('.', 2)
  "#{snake_to_class_name(camel_to_snake(domain))}::#{screaming_snake(local)}"
end

.enum_key(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

snake_case hash key for an enum value (only a label for the wire value it maps to). Preserves camelCase word boundaries (beforeRequestSent → before_request_sent), maps a leading minus to "neg" (-0 → neg0, -Infinity → neg_infinity; no underscore before a digit, so the key stays normalcase), collapses other punctuation (dedicated-worker → dedicated_worker), and prefixes a numeric value so the key is still a valid symbol (0 → _0).



152
153
154
155
156
157
158
159
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 152

def self.enum_key(value)
  token = camel_to_snake(value.to_s)
          .sub(/\A-(?=\d)/, 'neg')
          .sub(/\A-/, 'neg_')
          .gsub(/[^a-z0-9]+/, '_')
          .gsub(/\A_+|_+\z/, '')
  token.empty? || token.match?(/\A\d/) ? "_#{token}" : token
end

.error_class_name(code) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

WebDriver error-code string -> exception class name, matching Error.for_error's convention ("no such node" -> NoSuchNodeError). The Error suffix is normalized (not doubled) for a code already ending in "error" ("unknown error" -> UnknownError).



1513
1514
1515
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1513

def self.error_class_name(code)
  "#{code.split.map(&:capitalize).join.sub(/Error$/, '')}Error"
end

.error_code_map(schema) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The ErrorCode wire values mapped to their Ruby exception class names (schema order), e.g. "no such node" => "NoSuchNodeError". This is the schema->Ruby translation: the generated file carries the Ruby names, and a hand-written pass turns them into WebDriverError subclasses under the shared Error namespace. Self-contained — no reference to the classic error module.



1506
1507
1508
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1506

def self.error_code_map(schema)
  schema.error_codes.map { |code| [code, error_class_name(code)] }
end

.error_module_current?(schema, protocol_dir) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether the checked-in protocol/error_code.rb matches what the generator would render now.

Returns:

  • (Boolean)


45
46
47
48
49
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 45

def self.error_module_current?(schema, protocol_dir)
  mod = ErrorModule.new(filename: 'error_code', codes: error_code_map(schema))
  path = File.join(protocol_dir, 'error_code.rb')
  File.exist?(path) && File.read(path) == render(mod, File.join(__dir__, 'templates', 'error_code.rb.erb'))
end

.nest_synthetic(types) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The projector tags lifted-out types with owner, label. Emit each synthetic record inside its owner's class body under its bare label, so Owner_Label becomes the nested Owner::Label (refs resolve there via ruby_path). Synthetic enums stay domain-level. Raises on a missing owner.



1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1474

def self.nest_synthetic(types)
  index = types.to_h { |t| [t.schema_name, t] }
  children = types.select { |t| !t.union? && t.synthetic }
  children.each do |child|
    owner = index[child.owner] ||
            raise("synthetic type #{child.schema_name} has no emitted owner #{child.owner}")
    owner.nested = (owner.nested || []) << child
    child.ruby_name = child.label
  end
  types - children
end

.rbs_nilable(type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Makes an RBS type admit nil, idempotently (an already-nilable or opaque type is left as-is). Applied to a field whose schema type is nullable, so its value type allows nil; keyword-optionality is expressed separately by the ? prefix (see rbs_part / rbs_arg).



132
133
134
135
136
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 132

def self.rbs_nilable(type)
  return type if type == 'untyped' || type == 'nil' || type.end_with?('?')

  "#{type}?"
end

.render(mod, template_path) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1486
1487
1488
1489
1490
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1486

def self.render(mod, template_path)
  generated_note = GeneratedNote.render('#', 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb',
                                        'bazel run //rb/lib/selenium/webdriver:bidi-generate')
  ERB.new(File.read(template_path), trim_mode: '-').result(binding)
end

.ruby_literal(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Source literal for a discriminator/const value (string, boolean, or number).



83
84
85
86
87
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 83

def self.ruby_literal(value)
  return 'nil' if value.nil?

  value.is_a?(String) ? "'#{value}'" : value.to_s
end

.safe_field_name(name, extensible: true) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Append underscore to a field name that would shadow a core method; the wire name is unaffected, only the Ruby reader is renamed.



114
115
116
117
118
119
120
121
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 114

def self.safe_field_name(name, extensible: true)
  # A vendor-prefixed wire name carries a colon (moz:allowPrivateBrowsing); swap it
  # for an underscore so the Ruby reader is a legal identifier. The wire key is kept.
  name = name.tr(':', '_')
  # Only an extensible record holds its undeclared fields in an `extensions` member.
  reserved = RESERVED_FIELD_NAMES.include?(name) || (extensible && name == 'extensions')
  reserved ? "#{name}_" : name
end

.safe_method_name(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Append underscore to avoid clashing with Ruby reserved keywords.



101
102
103
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 101

def self.safe_method_name(name)
  RUBY_RESERVED.include?(name) ? "#{name}_" : name
end

.schema_path(rootpath) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

$(rootpath) is relative to the runfiles root; dir anchors us there so it resolves the same way locally and on RBE (an execpath would not). This file lives at rb/lib/selenium/webdriver/bidi/support, so expand six levels up to the root — File.expand_path is separator-agnostic, unlike stripping a "/"-spelled suffix (which would miss on Windows). The cwd-relative rootpath fallback matches how spec_support's rlocation resolves.



56
57
58
59
60
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 56

def self.schema_path(rootpath)
  runfiles_root = File.expand_path('../../../../../..', __dir__)
  [File.join(runfiles_root, rootpath), rootpath].find { |p| File.exist?(p) } ||
    raise("BiDi schema not found (looked for #{rootpath})")
end

.screaming_snake(camel) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

SCREAMING_SNAKE constant name for an enum, matching the EVENTS map style (ReadinessState → READINESS_STATE).



125
126
127
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 125

def self.screaming_snake(camel)
  camel_to_snake(camel).upcase
end

.sig_dir(output_dir) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The RBS signatures mirror the source tree under sig/ (the repo's convention), e.g. rb/lib/.../protocol -> rb/sig/lib/.../protocol.



1551
1552
1553
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1551

def self.sig_dir(output_dir)
  output_dir.sub(%r{(\A|/)lib/}, '\1sig/lib/')
end

.snake_to_class_name(snake) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



60
61
62
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 60

def self.snake_to_class_name(snake)
  snake.split('_').map(&:capitalize).join
end

.thread_variant_arg_sigs(schema, types) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Give each union its variants' typed new signatures, keyed by factory method name, so rbs_variant_factories can emit a checked signature instead of a splat. Keyed by ruby path (the form a variant ref carries); a cross-module variant not in this list falls back to **untyped.



1383
1384
1385
1386
1387
1388
1389
1390
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1383

def self.thread_variant_arg_sigs(schema, types)
  record_sigs = types.reject(&:union?).to_h { |t| [schema.ruby_path_for(t.schema_name), t.rbs_new_args] }
  types.select(&:union?).each do |union|
    union.variant_arg_sigs = union.value_variants.to_h do |variant|
      [BiDiGenerate.enum_key(variant.value), record_sigs[variant.ref]]
    end
  end
end

.type_class_name(type_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Local constant for a domain-scoped type: "script.LocalValue" -> "LocalValue". The first letter is capitalized so a lower-cased spec name (e.g. "permissions.setPermission") still yields a valid Ruby constant.



67
68
69
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 67

def self.type_class_name(type_name)
  type_name.split('.', 2).last.sub(/\A[a-z]/, &:upcase)
end

.type_ruby_path(type_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Protocol-relative class path: "script.LocalValue" -> "Script::LocalValue".



72
73
74
75
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 72

def self.type_ruby_path(type_name)
  domain = type_name.split('.', 2).first
  "#{snake_to_class_name(camel_to_snake(domain))}::#{type_class_name(type_name)}"
end

.vendor_accessors(vendor_modules) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An accessor per vendor variant, returning a sibling vendor domain over the same connection (web_extension.moz -> Moz.new(connection)). Named after the vendor namespace.



1372
1373
1374
1375
1376
1377
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1372

def self.vendor_accessors(vendor_modules)
  vendor_modules.map do |vendor_module|
    Accessor.new(method_name: safe_method_name(vendor_module.namespace), type_name: vendor_module.name,
                 union: false, vendor: true)
  end
end

.word_array(words) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Source literal for a list of wire keys, in the form RuboCop expects at each size.



78
79
80
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 78

def self.word_array(words)
  words.size > 1 ? "%w[#{words.join(' ')}]" : "[#{words.map { |w| "'#{w}'" }.join(', ')}]"
end

.wrap_call(prefix, args, indent, open: '(', close: ')') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Renders prefix(args) on one line, or one argument per line when it would exceed LINE_LIMIT at the given indent. open/close default to parentheses (pass {} for a hash literal) so emitted calls and literals stay within RuboCop's length limit.



92
93
94
95
96
97
98
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 92

def self.wrap_call(prefix, args, indent, open: '(', close: ')')
  one_line = "#{prefix}#{open}#{args.join(', ')}#{close}"
  return one_line if args.empty? || indent + one_line.length <= LINE_LIMIT

  pad = ' ' * (indent + 2)
  "#{prefix}#{open}\n#{pad}#{args.join(",\n#{pad}")}\n#{' ' * indent}#{close}"
end