From 8c317d89e6b88bb5a59c9e38a0485f3c15fa804e Mon Sep 17 00:00:00 2001 From: titusfortner Date: Sat, 22 Mar 2025 11:12:31 -0700 Subject: [PATCH 1/6] [build] allow tests tagged exclusive-if-local to run on rbe --- .bazelrc.remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bazelrc.remote b/.bazelrc.remote index 40f864f95cda2..7b50bef8b48f1 100644 --- a/.bazelrc.remote +++ b/.bazelrc.remote @@ -31,7 +31,7 @@ build:remote --disk_cache= build:remote --incompatible_enable_cc_toolchain_resolution build:remote --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 test:remote --test_env=DISPLAY=:99.0 -test:remote --test_tag_filters=-exclusive-if-local,-skip-rbe,-remote +test:remote --test_tag_filters=-skip-rbe,-remote # Env vars we can hard code build:remote --action_env=HOME=/home/dev From db643da53f860e862dea8f59333cdfabef5038ba Mon Sep 17 00:00:00 2001 From: aguspe Date: Wed, 30 Apr 2025 22:52:39 +0200 Subject: [PATCH 2/6] Implement RBS trace --- rb/Gemfile | 2 ++ rb/Gemfile.lock | 4 ++++ rb/lib/selenium/webdriver.rb | 1 + rb/lib/selenium/webdriver/chrome.rb | 1 + rb/lib/selenium/webdriver/chrome/driver.rb | 2 ++ rb/lib/selenium/webdriver/chrome/features.rb | 2 ++ rb/lib/selenium/webdriver/chrome/options.rb | 1 + rb/lib/selenium/webdriver/chrome/service.rb | 1 + rb/lib/selenium/webdriver/chromium/features.rb | 1 + rb/lib/selenium/webdriver/chromium/options.rb | 3 +++ rb/lib/selenium/webdriver/common/child_process.rb | 7 +++++++ rb/lib/selenium/webdriver/common/driver.rb | 8 ++++++++ .../webdriver/common/driver_extensions/has_cdp.rb | 1 + rb/lib/selenium/webdriver/common/driver_finder.rb | 6 ++++++ rb/lib/selenium/webdriver/common/error.rb | 1 + rb/lib/selenium/webdriver/common/local_driver.rb | 2 ++ rb/lib/selenium/webdriver/common/logger.rb | 2 ++ rb/lib/selenium/webdriver/common/navigation.rb | 2 ++ rb/lib/selenium/webdriver/common/options.rb | 9 +++++++++ rb/lib/selenium/webdriver/common/platform.rb | 15 +++++++++++++++ rb/lib/selenium/webdriver/common/port_prober.rb | 2 ++ .../selenium/webdriver/common/selenium_manager.rb | 6 ++++++ rb/lib/selenium/webdriver/common/service.rb | 5 +++++ .../selenium/webdriver/common/service_manager.rb | 14 ++++++++++++++ rb/lib/selenium/webdriver/common/socket_lock.rb | 7 +++++++ rb/lib/selenium/webdriver/common/socket_poller.rb | 8 ++++++++ rb/lib/selenium/webdriver/remote/bridge.rb | 13 +++++++++++++ rb/lib/selenium/webdriver/remote/capabilities.rb | 11 +++++++++++ rb/lib/selenium/webdriver/remote/http/common.rb | 5 +++++ rb/lib/selenium/webdriver/remote/http/default.rb | 10 ++++++++++ rb/lib/selenium/webdriver/remote/response.rb | 5 +++++ rb/lib/selenium/webdriver/support/guards.rb | 7 +++++++ rb/lib/selenium/webdriver/support/guards/guard.rb | 5 +++++ .../webdriver/support/guards/guard_condition.rb | 2 ++ .../selenium/webdriver/action_builder_spec.rb | 2 +- .../integration/selenium/webdriver/spec_helper.rb | 7 +++++++ .../selenium/webdriver/spec_support/helpers.rb | 3 +++ .../webdriver/spec_support/rack_server.rb | 5 +++++ .../webdriver/spec_support/test_environment.rb | 14 ++++++++++++++ 39 files changed, 201 insertions(+), 1 deletion(-) diff --git a/rb/Gemfile b/rb/Gemfile index 5c2c1d11f5954..9ea2d48cec7b6 100644 --- a/rb/Gemfile +++ b/rb/Gemfile @@ -10,3 +10,5 @@ gem 'activesupport', '~> 7.0', require: false, platforms: %i[mri mingw x64_mingw gem 'curb', '~> 1.0.5', require: false, platforms: %i[mri mingw x64_mingw] gem 'debug', '~> 1.7', require: false, platforms: %i[mri mingw x64_mingw] gem 'steep', '~> 1.5.0', require: false, platforms: %i[mri mingw x64_mingw] + +gem "rbs-trace", "~> 0.5.1" diff --git a/rb/Gemfile.lock b/rb/Gemfile.lock index e8c7ee96fc11c..e1d9ea2db0747 100644 --- a/rb/Gemfile.lock +++ b/rb/Gemfile.lock @@ -100,6 +100,9 @@ GEM ffi (~> 1.0) rbs (3.9.2) logger + rbs-trace (0.5.1) + prism (>= 0.3.0) + rbs (>= 3.5.0) rchardet (1.9.0) rdoc (6.13.1) psych (>= 4.0.0) @@ -199,6 +202,7 @@ DEPENDENCIES git (~> 1.19) rack (~> 2.0) rake (~> 13.0) + rbs-trace (~> 0.5.1) rspec (~> 3.0) rubocop (~> 1.75) rubocop-performance (~> 1.25) diff --git a/rb/lib/selenium/webdriver.rb b/rb/lib/selenium/webdriver.rb index 5b82fc1a0554d..ff39294d96999 100644 --- a/rb/lib/selenium/webdriver.rb +++ b/rb/lib/selenium/webdriver.rb @@ -95,6 +95,7 @@ def self.for(*args) # @return [Logger] # + # @rbs (**nil) -> Selenium::WebDriver::Logger def self.logger(**opts) level = $DEBUG || ENV.key?('DEBUG') ? :debug : :info @logger ||= WebDriver::Logger.new('Selenium', default_level: level, **opts) diff --git a/rb/lib/selenium/webdriver/chrome.rb b/rb/lib/selenium/webdriver/chrome.rb index 51595f65ca5cb..325cb25a28b41 100644 --- a/rb/lib/selenium/webdriver/chrome.rb +++ b/rb/lib/selenium/webdriver/chrome.rb @@ -31,6 +31,7 @@ def self.path=(path) @path = path end + # @rbs () -> nil def self.path @path ||= nil end diff --git a/rb/lib/selenium/webdriver/chrome/driver.rb b/rb/lib/selenium/webdriver/chrome/driver.rb index 46a0b1e321a91..91d6b18135a31 100644 --- a/rb/lib/selenium/webdriver/chrome/driver.rb +++ b/rb/lib/selenium/webdriver/chrome/driver.rb @@ -30,11 +30,13 @@ module Chrome class Driver < Chromium::Driver include LocalDriver + # @rbs (?options: Selenium::WebDriver::Chrome::Options, ?service: Selenium::WebDriver::Chrome::Service, ?url: nil, **nil) -> void def initialize(options: nil, service: nil, url: nil, **opts) caps, url = initialize_local_driver(options, service, url) super(caps: caps, url: url, **opts) end + # @rbs () -> Symbol def browser :chrome end diff --git a/rb/lib/selenium/webdriver/chrome/features.rb b/rb/lib/selenium/webdriver/chrome/features.rb index 976f659637e8a..3cd9d651d8f80 100644 --- a/rb/lib/selenium/webdriver/chrome/features.rb +++ b/rb/lib/selenium/webdriver/chrome/features.rb @@ -35,10 +35,12 @@ module Features send_command: [:post, 'session/:session_id/goog/cdp/execute'] }.freeze + # @rbs () -> Hash[untyped, untyped] def command_list CHROME_COMMANDS.merge(CHROMIUM_COMMANDS).merge(self.class::COMMANDS) end + # @rbs (Symbol) -> Array[untyped] def commands(command) command_list[command] end diff --git a/rb/lib/selenium/webdriver/chrome/options.rb b/rb/lib/selenium/webdriver/chrome/options.rb index 53cf789899c0e..2ac91c39505cd 100644 --- a/rb/lib/selenium/webdriver/chrome/options.rb +++ b/rb/lib/selenium/webdriver/chrome/options.rb @@ -32,6 +32,7 @@ def enable_logging(browser_options) browser_options['goog:loggingPrefs'] = @logging_prefs end + # @rbs () -> nil def binary_path Chrome.path end diff --git a/rb/lib/selenium/webdriver/chrome/service.rb b/rb/lib/selenium/webdriver/chrome/service.rb index 834c80d8ea461..01fce02a0766a 100644 --- a/rb/lib/selenium/webdriver/chrome/service.rb +++ b/rb/lib/selenium/webdriver/chrome/service.rb @@ -26,6 +26,7 @@ class Service < WebDriver::Service SHUTDOWN_SUPPORTED = true DRIVER_PATH_ENV_KEY = 'SE_CHROMEDRIVER' + # @rbs () -> nil def log return @log unless @log.is_a? String diff --git a/rb/lib/selenium/webdriver/chromium/features.rb b/rb/lib/selenium/webdriver/chromium/features.rb index 5333c6e21a16b..ad19eb8c48490 100644 --- a/rb/lib/selenium/webdriver/chromium/features.rb +++ b/rb/lib/selenium/webdriver/chromium/features.rb @@ -75,6 +75,7 @@ def delete_network_conditions execute :delete_network_conditions end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def send_command(command_params) execute :send_command, {}, command_params end diff --git a/rb/lib/selenium/webdriver/chromium/options.rb b/rb/lib/selenium/webdriver/chromium/options.rb index 7d7e59716a76e..3bea8c030fd56 100644 --- a/rb/lib/selenium/webdriver/chromium/options.rb +++ b/rb/lib/selenium/webdriver/chromium/options.rb @@ -67,6 +67,7 @@ class Options < WebDriver::Options # @option opts [Array] window_types A list of window types to appear in the list of window handles # + # @rbs (?profile: nil, **Array[untyped] | Hash[untyped, untyped] | nil) -> void def initialize(profile: nil, **opts) super(**opts) @@ -203,6 +204,7 @@ def enable_android(package: 'com.android.chrome', serial_number: nil, use_runnin protected + # @rbs (Hash[untyped, untyped]) -> void def process_browser_options(browser_options) enable_logging(browser_options) unless @logging_prefs.empty? @@ -234,6 +236,7 @@ def validate_extension(path) @extensions << path end + # @rbs (Symbol | String) -> bool def camelize?(key) !%w[localState prefs].include?(key) end diff --git a/rb/lib/selenium/webdriver/common/child_process.rb b/rb/lib/selenium/webdriver/common/child_process.rb index 41fd206616da6..5a7f8e7770446 100644 --- a/rb/lib/selenium/webdriver/common/child_process.rb +++ b/rb/lib/selenium/webdriver/common/child_process.rb @@ -34,10 +34,12 @@ class ChildProcess attr_accessor :detach attr_writer :io + # @rbs (*String) -> Selenium::WebDriver::ChildProcess def self.build(*command) new(*command) end + # @rbs (*String) -> void def initialize(*command) @command = command @detach = false @@ -45,10 +47,12 @@ def initialize(*command) @status = nil end + # @rbs () -> String def io @io ||= Platform.null_device end + # @rbs () -> nil def start options = {%i[out err] => io} options[:pgroup] = true unless Platform.windows? # NOTE: this is a bug only in Windows 7 @@ -74,6 +78,7 @@ def alive? @pid && !exited? end + # @rbs () -> bool def exited? return false unless @pid @@ -90,6 +95,7 @@ def exited? true end + # @rbs (Integer) -> nil def poll_for_exit(timeout) WebDriver.logger.debug("Polling #{timeout} seconds for exit of #{@pid}", id: :process) @@ -128,6 +134,7 @@ def kill(pid) Process.kill(SIGKILL, pid) end + # @rbs (Integer, ?Integer) -> Array[untyped]? def waitpid2(pid, flags = 0) Process.waitpid2(pid, flags) end diff --git a/rb/lib/selenium/webdriver/common/driver.rb b/rb/lib/selenium/webdriver/common/driver.rb index ed911cb275f45..1d7a104cddf5f 100644 --- a/rb/lib/selenium/webdriver/common/driver.rb +++ b/rb/lib/selenium/webdriver/common/driver.rb @@ -41,6 +41,7 @@ class << self # @return [Driver] # + # @rbs (Symbol, ?Hash[untyped, untyped]) -> Selenium::WebDriver::Chrome::Driver def for(browser, opts = {}) case browser when :chrome, :chrome_headless_shell @@ -68,6 +69,7 @@ def for(browser, opts = {}) # @api private # + # @rbs (?bridge: nil, ?listener: nil, **Hash[untyped, untyped] | URI::HTTP) -> void def initialize(bridge: nil, listener: nil, **opts) @devtools = nil bridge ||= create_bridge(**opts) @@ -95,6 +97,7 @@ def status # @see Navigation # + # @rbs () -> Selenium::WebDriver::Navigation def navigate @navigate ||= WebDriver::Navigation.new(bridge) end @@ -177,6 +180,7 @@ def page_source # Quit the browser # + # @rbs () -> nil def quit bridge.quit ensure @@ -225,6 +229,7 @@ def window_handle # The value returned from the script. # + # @rbs (String, *nil) -> String def execute_script(script, *args) bridge.execute_script(script, *args) end @@ -319,6 +324,7 @@ def ref attr_reader :bridge + # @rbs (caps: Hash[untyped, untyped], url: URI::HTTP, ?http_client: nil) -> Selenium::WebDriver::Remote::Bridge def create_bridge(caps:, url:, http_client: nil) klass = caps['webSocketUrl'] ? Remote::BiDiBridge : Remote::Bridge klass.new(http_client: http_client, url: url).tap do |bridge| @@ -326,6 +332,7 @@ def create_bridge(caps:, url:, http_client: nil) end end + # @rbs (Selenium::WebDriver::Chrome::Service) -> URI::HTTP def service_url(service) @service_manager = service.launch @service_manager.uri @@ -335,6 +342,7 @@ def screenshot bridge.screenshot end + # @rbs (Symbol) -> Array[untyped] def add_extensions(browser) extensions = case browser when :chrome, :chrome_headless_shell, :msedge, :microsoftedge diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb index de8d2636f8ab5..ce8e81bf263d0 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb @@ -27,6 +27,7 @@ module HasCDP # @return [Hash] # + # @rbs (String, **String) -> Hash[untyped, untyped] def execute_cdp(cmd, **params) @bridge.send_command(cmd: cmd, params: params) end diff --git a/rb/lib/selenium/webdriver/common/driver_finder.rb b/rb/lib/selenium/webdriver/common/driver_finder.rb index 8e5be138d6046..62d54e9d2196e 100644 --- a/rb/lib/selenium/webdriver/common/driver_finder.rb +++ b/rb/lib/selenium/webdriver/common/driver_finder.rb @@ -26,25 +26,30 @@ def self.path(options, service_class) new(options, service_class.new).driver_path end + # @rbs (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service) -> void def initialize(options, service) @options = options @service = service end + # @rbs () -> String def browser_path paths[:browser_path] end + # @rbs () -> String def driver_path paths[:driver_path] end + # @rbs () -> bool def browser_path? !browser_path.nil? && !browser_path.empty? end private + # @rbs () -> Hash[untyped, untyped] def paths @paths ||= begin path = @service.class.driver_path @@ -76,6 +81,7 @@ def paths end end + # @rbs () -> Array[untyped] def to_args args = ['--browser', @options.browser_name] if @options.browser_version diff --git a/rb/lib/selenium/webdriver/common/error.rb b/rb/lib/selenium/webdriver/common/error.rb index ed452cb7377df..d50a4c83b6798 100644 --- a/rb/lib/selenium/webdriver/common/error.rb +++ b/rb/lib/selenium/webdriver/common/error.rb @@ -25,6 +25,7 @@ module Error # @param [String, nil] error # + # @rbs (nil) -> nil def self.for_error(error) return if error.nil? diff --git a/rb/lib/selenium/webdriver/common/local_driver.rb b/rb/lib/selenium/webdriver/common/local_driver.rb index 0e20ca01d8ecc..bf453ea73c5de 100644 --- a/rb/lib/selenium/webdriver/common/local_driver.rb +++ b/rb/lib/selenium/webdriver/common/local_driver.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver module LocalDriver + # @rbs (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service, nil) -> Array[untyped] def initialize_local_driver(options, service, url) raise ArgumentError, "Can't initialize #{self.class} with :url" if url @@ -30,6 +31,7 @@ def initialize_local_driver(options, service, url) [caps, url] end + # @rbs (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service) -> Hash[untyped, untyped] def process_options(options, service) default_options = Options.send(browser) options ||= default_options diff --git a/rb/lib/selenium/webdriver/common/logger.rb b/rb/lib/selenium/webdriver/common/logger.rb index 7fd2f5c169e4a..a7440f326c760 100644 --- a/rb/lib/selenium/webdriver/common/logger.rb +++ b/rb/lib/selenium/webdriver/common/logger.rb @@ -115,6 +115,7 @@ def allow(*ids) # @param [Symbol, Array] id # @yield see #deprecate # + # @rbs (String, ?id: Array[untyped] | Symbol) -> nil def debug(message, id: [], &block) discard_or_log(:debug, message, id, &block) end @@ -191,6 +192,7 @@ def create_logger(name, level:) logger end + # @rbs (Symbol, String, Array[untyped] | Symbol) -> nil def discard_or_log(level, message, id) id = Array(id) return if @ignored.intersect?(id) diff --git a/rb/lib/selenium/webdriver/common/navigation.rb b/rb/lib/selenium/webdriver/common/navigation.rb index 585f46dee7aeb..80d2345c486b1 100644 --- a/rb/lib/selenium/webdriver/common/navigation.rb +++ b/rb/lib/selenium/webdriver/common/navigation.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver class Navigation + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end @@ -28,6 +29,7 @@ def initialize(bridge) # Navigate to the given URL # + # @rbs (String) -> void def to(url) @bridge.get url end diff --git a/rb/lib/selenium/webdriver/common/options.rb b/rb/lib/selenium/webdriver/common/options.rb index 71205f79a734d..4b815b9e84703 100644 --- a/rb/lib/selenium/webdriver/common/options.rb +++ b/rb/lib/selenium/webdriver/common/options.rb @@ -29,6 +29,7 @@ class Options class << self attr_reader :driver_path + # @rbs (**Array[untyped] | Hash[untyped, untyped] | nil) -> Selenium::WebDriver::Chrome::Options def chrome(**opts) Chrome::Options.new(**opts) end @@ -68,6 +69,7 @@ def set_capabilities attr_accessor :options + # @rbs (**Array[untyped] | Hash[untyped, untyped] | nil) -> void def initialize(**opts) self.class.set_capabilities @@ -103,6 +105,7 @@ def ==(other) # @api private # + # @rbs (*untyped) -> Hash[untyped, untyped] def as_json(*) options = @options.dup @@ -125,10 +128,12 @@ def as_json(*) private + # @rbs (Symbol) -> bool def w3c?(key) W3C_OPTIONS.include?(key) || key.to_s.include?(':') end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def process_w3c_options(options) w3c_options = options.select { |key, val| w3c?(key) && !val.nil? } w3c_options[:unhandled_prompt_behavior] &&= w3c_options[:unhandled_prompt_behavior]&.to_s&.tr('_', ' ') @@ -144,6 +149,7 @@ def camelize?(_key) true end + # @rbs (String | Array[untyped] | Hash[untyped, untyped], ?camelize_keys: bool) -> (String | Array[untyped] | Hash[untyped, untyped]) def generate_as_json(value, camelize_keys: true) if value.is_a?(Hash) process_json_hash(value, camelize_keys) @@ -158,6 +164,7 @@ def generate_as_json(value, camelize_keys: true) end end + # @rbs (Hash[untyped, untyped], bool) -> Hash[untyped, untyped] def process_json_hash(value, camelize_keys) value.each_with_object({}) do |(key, val), hash| next if val.respond_to?(:empty?) && val.empty? @@ -168,6 +175,7 @@ def process_json_hash(value, camelize_keys) end end + # @rbs (Symbol | String, ?camelize: bool) -> String def convert_json_key(key, camelize: true) key = key.to_s if key.is_a?(Symbol) key = camel_case(key) if camelize @@ -176,6 +184,7 @@ def convert_json_key(key, camelize: true) raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}" end + # @rbs (String) -> String def camel_case(str) str.gsub(/_([a-z])/) { Regexp.last_match(1)&.upcase } end diff --git a/rb/lib/selenium/webdriver/common/platform.rb b/rb/lib/selenium/webdriver/common/platform.rb index 4d326b9fee5ce..c34f14f7f7acc 100644 --- a/rb/lib/selenium/webdriver/common/platform.rb +++ b/rb/lib/selenium/webdriver/common/platform.rb @@ -30,10 +30,12 @@ def home @home ||= Dir.home end + # @rbs () -> Symbol def engine @engine ||= RUBY_ENGINE.to_sym end + # @rbs () -> Symbol def os host_os = RbConfig::CONFIG['host_os'] @os ||= case host_os @@ -50,6 +52,7 @@ def os end end + # @rbs () -> nil def ci if ENV['TRAVIS'] :travis @@ -62,10 +65,12 @@ def ci end end + # @rbs () -> bool def jruby? engine == :jruby end + # @rbs () -> bool def truffleruby? engine == :truffleruby end @@ -74,6 +79,7 @@ def ruby_version RUBY_VERSION end + # @rbs () -> bool def windows? os == :windows end @@ -99,10 +105,12 @@ def wsl? false end + # @rbs () -> bool def cygwin? RUBY_PLATFORM.include?('cygwin') end + # @rbs () -> String def null_device File::NULL end @@ -111,6 +119,7 @@ def wrap_in_quotes_if_necessary(str) windows? && !cygwin? ? %("#{str}") : str end + # @rbs (String, ?only_cygwin: bool, **nil) -> String def cygwin_path(path, only_cygwin: false, **opts) return path if only_cygwin && !cygwin? @@ -132,12 +141,14 @@ def make_writable(file) File.chmod 0o766, file end + # @rbs (String) -> void def assert_file(path) return if File.file? path raise Error::WebDriverError, "not a file: #{path.inspect}" end + # @rbs (String) -> void def assert_executable(path) assert_file(path) @@ -146,12 +157,14 @@ def assert_executable(path) raise Error::WebDriverError, "not executable: #{path.inspect}" end + # @rbs () -> void def exit_hook pid = Process.pid at_exit { yield if Process.pid == pid } end + # @rbs () -> String def localhost info = Socket.getaddrinfo 'localhost', 80, Socket::AF_INET, Socket::SOCK_STREAM @@ -160,6 +173,7 @@ def localhost raise Error::WebDriverError, "unable to translate 'localhost' for TCP + IPv4" end + # @rbs () -> String def ip orig = Socket.do_not_reverse_lookup Socket.do_not_reverse_lookup = true @@ -176,6 +190,7 @@ def ip # no external ip end + # @rbs () -> Array[untyped] def interfaces interfaces = Socket.getaddrinfo('localhost', 8080).map { |e| e[3] } interfaces += ['0.0.0.0', Platform.ip] diff --git a/rb/lib/selenium/webdriver/common/port_prober.rb b/rb/lib/selenium/webdriver/common/port_prober.rb index e8622920a7dca..87f8b443d482d 100644 --- a/rb/lib/selenium/webdriver/common/port_prober.rb +++ b/rb/lib/selenium/webdriver/common/port_prober.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver class PortProber + # @rbs (Integer) -> Integer def self.above(port) port += 1 until free? port port @@ -30,6 +31,7 @@ def self.above(port) arr << Errno::EACCES if Platform.windows? }.freeze + # @rbs (Integer) -> bool def self.free?(port) Platform.interfaces.each do |host| TCPServer.new(host, port).close diff --git a/rb/lib/selenium/webdriver/common/selenium_manager.rb b/rb/lib/selenium/webdriver/common/selenium_manager.rb index 4a8603b6584b0..bb5c2520a4c91 100644 --- a/rb/lib/selenium/webdriver/common/selenium_manager.rb +++ b/rb/lib/selenium/webdriver/common/selenium_manager.rb @@ -36,6 +36,7 @@ def bin_path # @param [Array] arguments what gets sent to to Selenium Manager binary. # @return [Hash] paths to the requested assets. + # @rbs (*String) -> Hash[untyped, untyped] def binary_paths(*arguments) arguments += %w[--language-binding ruby] arguments += %w[--output json] @@ -47,6 +48,7 @@ def binary_paths(*arguments) private # @return [String] the path to the correct selenium manager + # @rbs () -> String def binary @binary ||= begin if (location = ENV.fetch('SE_MANAGER_PATH', nil)) @@ -60,6 +62,7 @@ def binary end end + # @rbs (*String) -> Hash[untyped, untyped] def run(*command) stdout, stderr, status = execute_command(*command) result = parse_result_and_log(stdout) @@ -86,6 +89,7 @@ def platform_location end end + # @rbs (*String) -> Array[untyped] def execute_command(*command) WebDriver.logger.debug("Executing Process #{command}", id: :selenium_manager) @@ -94,6 +98,7 @@ def execute_command(*command) raise Error::WebDriverError, "Unsuccessful command executed: #{command}; #{e.message}" end + # @rbs (String) -> Hash[untyped, untyped] def parse_result_and_log(stdout) json_output = stdout.empty? ? {'logs' => [], 'result' => {}} : JSON.parse(stdout) @@ -105,6 +110,7 @@ def parse_result_and_log(stdout) json_output['result'] end + # @rbs (Array[untyped], Process::Status, Hash[untyped, untyped], String) -> void def validate_command_result(command, status, result, stderr) if status.nil? || status.exitstatus.nil? WebDriver.logger.info("No exit status for: #{command}. Assuming success if result is present.", diff --git a/rb/lib/selenium/webdriver/common/service.rb b/rb/lib/selenium/webdriver/common/service.rb index b0f274959ebeb..fe31efb772e04 100644 --- a/rb/lib/selenium/webdriver/common/service.rb +++ b/rb/lib/selenium/webdriver/common/service.rb @@ -28,6 +28,7 @@ class Service class << self attr_reader :driver_path + # @rbs (**nil) -> Selenium::WebDriver::Chrome::Service def chrome(**opts) Chrome::Service.new(**opts) end @@ -66,6 +67,7 @@ def driver_path=(path) # @api private # + # @rbs (?path: nil, ?port: nil, ?log: nil, ?args: nil) -> void def initialize(path: nil, port: nil, log: nil, args: nil) port ||= self.class::DEFAULT_PORT args ||= [] @@ -87,11 +89,13 @@ def initialize(path: nil, port: nil, log: nil, args: nil) raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1 end + # @rbs () -> Selenium::WebDriver::ServiceManager def launch @executable_path ||= env_path || find_driver_path ServiceManager.new(self).tap(&:start) end + # @rbs () -> bool def shutdown_supported self.class::SHUTDOWN_SUPPORTED end @@ -101,6 +105,7 @@ def find_driver_path DriverFinder.new(default_options, self).driver_path end + # @rbs () -> nil def env_path ENV.fetch(self.class::DRIVER_PATH_ENV_KEY, nil) end diff --git a/rb/lib/selenium/webdriver/common/service_manager.rb b/rb/lib/selenium/webdriver/common/service_manager.rb index c93e2d688c03e..b1c5533772384 100644 --- a/rb/lib/selenium/webdriver/common/service_manager.rb +++ b/rb/lib/selenium/webdriver/common/service_manager.rb @@ -36,6 +36,7 @@ class ServiceManager # @api private # + # @rbs (Selenium::WebDriver::Chrome::Service) -> void def initialize(config) @executable_path = config.executable_path @host = Platform.localhost @@ -47,6 +48,7 @@ def initialize(config) raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1 end + # @rbs () -> void def start raise "already started: #{uri.inspect} #{@executable_path.inspect}" if process_running? @@ -59,6 +61,7 @@ def start end end + # @rbs () -> void def stop return unless @shutdown_supported return if process_exited? @@ -71,12 +74,14 @@ def stop stop_process end + # @rbs () -> URI::HTTP def uri @uri ||= URI.parse("http://#{@host}:#{@port}") end private + # @rbs (*String) -> Selenium::WebDriver::ChildProcess def build_process(*command) WebDriver.logger.debug("Executing Process #{command}", id: :driver_service) @process = ChildProcess.build(*command) @@ -86,6 +91,7 @@ def build_process(*command) @process end + # @rbs () -> Net::HTTPOK def connect_to_server Net::HTTP.start(@host, @port) do |http| http.open_timeout = STOP_TIMEOUT / 2 @@ -95,21 +101,25 @@ def connect_to_server end end + # @rbs () -> void def find_free_port @port = PortProber.above(@port) end + # @rbs () -> void def start_process @process = build_process(@executable_path, "--port=#{@port}", *@extra_args) @process.start end + # @rbs () -> nil def stop_process return if process_exited? @process.stop STOP_TIMEOUT end + # @rbs () -> void def stop_server connect_to_server do |http| headers = WebDriver::Remote::Http::Common::DEFAULT_HEADERS.dup @@ -118,14 +128,17 @@ def stop_server end end + # @rbs () -> nil def process_running? defined?(@process) && @process&.alive? end + # @rbs () -> bool def process_exited? @process.nil? || @process.exited? end + # @rbs () -> nil def connect_until_stable socket_poller = SocketPoller.new @host, @port, START_TIMEOUT return if socket_poller.connected? @@ -137,6 +150,7 @@ def cannot_connect_error_text "unable to connect to #{@executable_path} #{@host}:#{@port}" end + # @rbs () -> Selenium::WebDriver::SocketLock def socket_lock @socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT) end diff --git a/rb/lib/selenium/webdriver/common/socket_lock.rb b/rb/lib/selenium/webdriver/common/socket_lock.rb index e3189b92eae12..1d57c51882db6 100644 --- a/rb/lib/selenium/webdriver/common/socket_lock.rb +++ b/rb/lib/selenium/webdriver/common/socket_lock.rb @@ -24,6 +24,7 @@ module WebDriver # class SocketLock + # @rbs (Integer, Integer) -> void def initialize(port, timeout) @port = port @server = nil @@ -35,6 +36,7 @@ def initialize(port, timeout) # execution block if the lock could be successfully obtained. # + # @rbs () -> nil def locked lock @@ -47,6 +49,7 @@ def locked private + # @rbs () -> void def lock max_time = current_time + @timeout @@ -57,14 +60,17 @@ def lock raise Error::WebDriverError, "unable to bind to locking port #{@port} within #{@timeout} seconds" end + # @rbs () -> Float def current_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end + # @rbs () -> nil def release @server&.close end + # @rbs () -> bool def can_lock? @server = TCPServer.new(Platform.localhost, @port) @server.close_on_exec = true @@ -74,6 +80,7 @@ def can_lock? false end + # @rbs () -> bool def did_lock? !@server.nil? end diff --git a/rb/lib/selenium/webdriver/common/socket_poller.rb b/rb/lib/selenium/webdriver/common/socket_poller.rb index a638454a026ba..b14884236cbe0 100644 --- a/rb/lib/selenium/webdriver/common/socket_poller.rb +++ b/rb/lib/selenium/webdriver/common/socket_poller.rb @@ -23,6 +23,7 @@ module Selenium module WebDriver class SocketPoller + # @rbs (String, Integer, ?Integer, ?Float) -> void def initialize(host, port, timeout = 0, interval = 0.25) @host = host @port = Integer(port) @@ -37,6 +38,7 @@ def initialize(host, port, timeout = 0, interval = 0.25) # @return [Boolean] # + # @rbs () -> bool def connected? with_timeout { listening? } end @@ -68,6 +70,7 @@ def closed? if Platform.jruby? # we use a plain TCPSocket here since JRuby has issues closing socket # see https://github.com/jruby/jruby/issues/5709 + # @rbs () -> bool def listening? TCPSocket.new(@host, @port).close true @@ -75,6 +78,7 @@ def listening? false end else + # @rbs () -> bool def listening? addr = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM) sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) @@ -98,14 +102,17 @@ def listening? end end + # @rbs (Socket) -> Socket def socket_writable?(sock) sock.wait_writable(CONNECT_TIMEOUT) end + # @rbs (Socket) -> bool def conn_completed?(sock) sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR).int.zero? end + # @rbs () -> bool def with_timeout max_time = current_time + @timeout @@ -118,6 +125,7 @@ def with_timeout false end + # @rbs () -> Float def current_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end diff --git a/rb/lib/selenium/webdriver/remote/bridge.rb b/rb/lib/selenium/webdriver/remote/bridge.rb index d4318a25b0088..8be67dcab2230 100644 --- a/rb/lib/selenium/webdriver/remote/bridge.rb +++ b/rb/lib/selenium/webdriver/remote/bridge.rb @@ -41,6 +41,7 @@ def add_command(name, verb, url, &block) define_method(name, &block) end + # @rbs () -> Selenium::WebDriver::Remote::Bridge::LocatorConverter def locator_converter @locator_converter ||= LocatorConverter.new end @@ -57,6 +58,7 @@ def element_class # @api private # + # @rbs (url: URI::HTTP, ?http_client: nil) -> void def initialize(url:, http_client: nil) uri = url.is_a?(URI) ? url : URI.parse(url) uri.path += '/' unless uri.path.end_with?('/') @@ -72,6 +74,7 @@ def initialize(url:, http_client: nil) # Creates session. # + # @rbs (Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Bridge def create_session(capabilities) response = execute(:new_session, {}, prepare_capabilities_payload(capabilities)) @@ -100,10 +103,12 @@ def create_session(capabilities) # Returns the current session ID. # + # @rbs () -> String def session_id @session_id || raise(Error::WebDriverError, 'no current session exists') end + # @rbs () -> Symbol def browser @browser ||= begin name = @capabilities.browser_name @@ -115,6 +120,7 @@ def status execute :status end + # @rbs (String) -> nil def get(url) execute :get, {}, {url: url} end @@ -208,6 +214,7 @@ def switch_to_default_content QUIT_ERRORS = [IOError].freeze + # @rbs () -> nil def quit execute :delete_session http.close @@ -300,6 +307,7 @@ def element_screenshot(element) # javascript execution # + # @rbs (String, *nil) -> String def execute_script(script, *args) result = execute :execute_script, {}, {script: script, args: args} unwrap_script_result result @@ -597,6 +605,7 @@ def bidi raise(WebDriver::Error::WebDriverError, msg) end + # @rbs () -> Hash[untyped, untyped] def command_list COMMANDS end @@ -609,6 +618,7 @@ def command_list # @return [WebDriver::Remote::Response] # + # @rbs (Symbol, ?Hash[untyped, untyped], ?Hash[untyped, untyped]?) -> (Hash[untyped, untyped] | String)? def execute(command, opts = {}, command_hash = nil) verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}") path = path.dup @@ -629,10 +639,12 @@ def escaper @escaper ||= defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER end + # @rbs (Symbol) -> Array[untyped] def commands(command) command_list[command] || Bridge.extra_commands[command] end + # @rbs (String) -> String def unwrap_script_result(arg) case arg when Array @@ -658,6 +670,7 @@ def shadow_root_id_from(id) id[ShadowRoot::ROOT_KEY] end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def prepare_capabilities_payload(capabilities) capabilities = {alwaysMatch: capabilities} if !capabilities['alwaysMatch'] && !capabilities['firstMatch'] {capabilities: capabilities} diff --git a/rb/lib/selenium/webdriver/remote/capabilities.rb b/rb/lib/selenium/webdriver/remote/capabilities.rb index ce6b59d461bc6..76e3c8b1a5b24 100644 --- a/rb/lib/selenium/webdriver/remote/capabilities.rb +++ b/rb/lib/selenium/webdriver/remote/capabilities.rb @@ -70,6 +70,7 @@ def first_match(*capabilities) # @api private # + # @rbs (Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Capabilities def json_create(data) data = data.dup caps = new @@ -98,12 +99,14 @@ def json_create(data) caps end + # @rbs (Symbol) -> String def camel_case(str_or_sym) str_or_sym.to_s.gsub(/_([a-z])/) { Regexp.last_match(1)&.upcase } end private + # @rbs (Selenium::WebDriver::Remote::Capabilities, Hash[untyped, untyped]) -> void def process_timeouts(caps, timeouts) return if timeouts.nil? @@ -124,6 +127,7 @@ def process_timeouts(caps, timeouts) # @api public # + # @rbs (?Hash[untyped, untyped]) -> void def initialize(opts = {}) @capabilities = {} self.proxy = opts.delete(:proxy) if opts[:proxy] @@ -134,14 +138,17 @@ def initialize(opts = {}) # Allows setting arbitrary capabilities. # + # @rbs (Symbol, String | bool) -> (String | bool) def []=(key, value) @capabilities[key] = value end + # @rbs (Symbol) -> String def [](key) @capabilities[key] end + # @rbs (Hash[untyped, untyped]) -> void def merge!(other) if other.respond_to?(:capabilities, true) && other.capabilities.is_a?(Hash) @capabilities.merge! other.capabilities @@ -167,6 +174,7 @@ def proxy=(proxy) end end + # @rbs () -> Hash[untyped, untyped] def timeouts @capabilities[:timeouts] ||= {} end @@ -179,6 +187,7 @@ def implicit_timeout timeouts[:implicit] end + # @rbs (Integer) -> void def implicit_timeout=(timeout) timeouts[:implicit] = timeout end @@ -187,6 +196,7 @@ def page_load_timeout timeouts[:page_load] || timeouts[:pageLoad] end + # @rbs (Integer) -> void def page_load_timeout=(timeout) timeouts[:page_load] = timeout end @@ -195,6 +205,7 @@ def script_timeout timeouts[:script] end + # @rbs (Integer) -> Integer def script_timeout=(timeout) timeouts[:script] = timeout end diff --git a/rb/lib/selenium/webdriver/remote/http/common.rb b/rb/lib/selenium/webdriver/remote/http/common.rb index 2f287e2703132..114071417ae5e 100644 --- a/rb/lib/selenium/webdriver/remote/http/common.rb +++ b/rb/lib/selenium/webdriver/remote/http/common.rb @@ -33,6 +33,7 @@ class << self attr_accessor :extra_headers attr_writer :user_agent + # @rbs () -> String def user_agent @user_agent ||= "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})" end @@ -49,6 +50,7 @@ def close end # steep:ignore:start + # @rbs (Symbol, String, Hash[untyped, untyped]?) -> Selenium::WebDriver::Remote::Response def call(verb, url, command_hash) url = server_url.merge(url) unless url.is_a?(URI) headers = common_headers.dup @@ -71,6 +73,7 @@ def call(verb, url, command_hash) private + # @rbs () -> Hash[untyped, untyped] def common_headers @common_headers ||= begin headers = DEFAULT_HEADERS.dup @@ -81,6 +84,7 @@ def common_headers end end + # @rbs () -> URI::HTTP def server_url return @server_url if @server_url @@ -91,6 +95,7 @@ def request(*) raise NotImplementedError, 'subclass responsibility' end + # @rbs (String, String, String) -> Selenium::WebDriver::Remote::Response def create_response(code, body, content_type) code = code.to_i body = body.to_s.strip diff --git a/rb/lib/selenium/webdriver/remote/http/default.rb b/rb/lib/selenium/webdriver/remote/http/default.rb index 2677eefc2de15..1fbefe9784fcf 100644 --- a/rb/lib/selenium/webdriver/remote/http/default.rb +++ b/rb/lib/selenium/webdriver/remote/http/default.rb @@ -33,18 +33,21 @@ class Default < Common # Debuggers that freeze the process will not be able to evaluate any operations if that happens. # @param [Numeric] open_timeout - Open timeout to apply to HTTP client. # @param [Numeric] read_timeout - Read timeout (seconds) to apply to HTTP client. + # @rbs (?open_timeout: nil, ?read_timeout: nil) -> void def initialize(open_timeout: nil, read_timeout: nil) @open_timeout = open_timeout @read_timeout = read_timeout super() end + # @rbs () -> nil def close @http&.finish end private + # @rbs () -> Net::HTTP def http @http ||= begin http = new_http_client @@ -61,12 +64,14 @@ def http end end + # @rbs (Net::HTTP) -> void def start(http) http.start end MAX_RETRIES = 3 + # @rbs (Symbol, URI::HTTP, Hash[untyped, untyped], String?, ?Integer) -> Selenium::WebDriver::Remote::Response def request(verb, url, headers, payload, redirects = 0) retries = 0 @@ -104,6 +109,7 @@ def request(verb, url, headers, payload, redirects = 0) end end + # @rbs (Symbol, URI::HTTP, Hash[untyped, untyped], String?) -> (Net::HTTP::Delete | Net::HTTP::Post) def new_request_for(verb, url, headers, payload) req = Net::HTTP.const_get(verb.to_s.capitalize).new(url.path, headers) @@ -114,10 +120,12 @@ def new_request_for(verb, url, headers, payload) req end + # @rbs (Net::HTTP::Delete | Net::HTTP::Post) -> Net::HTTPOK def response_for(request) http.request request end + # @rbs () -> Net::HTTP def new_http_client if use_proxy? url = @proxy.http @@ -134,6 +142,7 @@ def new_http_client end end + # @rbs () -> nil def proxy @proxy ||= begin proxy = ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil) @@ -146,6 +155,7 @@ def proxy end end + # @rbs () -> bool def use_proxy? return false if proxy.nil? diff --git a/rb/lib/selenium/webdriver/remote/response.rb b/rb/lib/selenium/webdriver/remote/response.rb index ce544b948964e..83f58ff5a308f 100644 --- a/rb/lib/selenium/webdriver/remote/response.rb +++ b/rb/lib/selenium/webdriver/remote/response.rb @@ -27,6 +27,7 @@ module Remote class Response attr_reader :code, :payload + # @rbs (Integer, ?Hash[untyped, untyped]) -> void def initialize(code, payload = nil) @code = code @payload = payload || {} @@ -34,6 +35,7 @@ def initialize(code, payload = nil) assert_ok end + # @rbs () -> nil def error error, message, backtrace = process_error klass = Error.for_error(error) || return @@ -42,12 +44,14 @@ def error ex end + # @rbs (String) -> (Hash[untyped, untyped] | String)? def [](key) @payload[key] end private + # @rbs () -> nil def assert_ok e = error raise e if e @@ -82,6 +86,7 @@ def backtrace_from_remote(server_trace) end end + # @rbs () -> Array[untyped]? def process_error return unless self['value'].is_a?(Hash) diff --git a/rb/lib/selenium/webdriver/support/guards.rb b/rb/lib/selenium/webdriver/support/guards.rb index 7b021021f6816..951776a2caf47 100644 --- a/rb/lib/selenium/webdriver/support/guards.rb +++ b/rb/lib/selenium/webdriver/support/guards.rb @@ -29,6 +29,7 @@ class Guards attr_reader :messages attr_accessor :bug_tracker + # @rbs (RSpec::Core::Example, ?bug_tracker: String, ?conditions: nil) -> void def initialize(example, bug_tracker: '', conditions: nil) @example = example @bug_tracker = bug_tracker @@ -37,6 +38,7 @@ def initialize(example, bug_tracker: '', conditions: nil) @messages = {} end + # @rbs (Symbol, ?(Symbol | bool)?) -> void def add_condition(name, condition = false, &block) condition = false if condition.nil? @guard_conditions << GuardCondition.new(name, condition, &block) @@ -47,6 +49,7 @@ def add_message(name, message) @messages[name] = message end + # @rbs () -> nil def disposition if !skipping_guard.nil? [:skip, skipping_guard.message] @@ -57,12 +60,14 @@ def disposition end end + # @rbs (Selenium::WebDriver::Support::Guards::Guard) -> bool def satisfied?(guard) @guard_conditions.all? { |condition| condition.satisfied?(guard) } end private + # @rbs () -> Array[untyped] def collect_example_guards guards = [] @@ -82,11 +87,13 @@ def collect_example_guards guards end + # @rbs () -> nil def skipping_guard @guards.select(&:exclusive?).find { |guard| !satisfied?(guard) } || @guards.select(&:exclude?).find { |guard| satisfied?(guard) } end + # @rbs () -> nil def pending_guard @guards.select(&:except?).find { |guard| satisfied?(guard) } || @guards.select(&:only?).find { |guard| !satisfied?(guard) } diff --git a/rb/lib/selenium/webdriver/support/guards/guard.rb b/rb/lib/selenium/webdriver/support/guards/guard.rb index 2bd46fb4494d1..21187fa45d6af 100644 --- a/rb/lib/selenium/webdriver/support/guards/guard.rb +++ b/rb/lib/selenium/webdriver/support/guards/guard.rb @@ -29,6 +29,7 @@ class Guards class Guard attr_reader :guarded, :type, :messages, :reason, :tracker + # @rbs (Hash[untyped, untyped], Symbol, ?Selenium::WebDriver::Support::Guards) -> void def initialize(guarded, type, guards = nil) @guarded = guarded @tracker = guards&.bug_tracker || '' @@ -63,22 +64,26 @@ def message end # Bug is present on all configurations specified + # @rbs () -> bool def except? @type == :except end # Bug is present on all configurations not specified + # @rbs () -> bool def only? @type == :only end # Bug is present on all configurations specified, but test can not be run because it breaks other tests, # or it is flaky and unreliable + # @rbs () -> bool def exclude? @type == :exclude || @type == :flaky end # Test only applies to configurations specified + # @rbs () -> bool def exclusive? @type == :exclusive end diff --git a/rb/lib/selenium/webdriver/support/guards/guard_condition.rb b/rb/lib/selenium/webdriver/support/guards/guard_condition.rb index 0efb2f2442863..a6c01589142f1 100644 --- a/rb/lib/selenium/webdriver/support/guards/guard_condition.rb +++ b/rb/lib/selenium/webdriver/support/guards/guard_condition.rb @@ -29,6 +29,7 @@ class Guards class GuardCondition attr_accessor :name, :execution + # @rbs (Symbol, ?Symbol | bool) -> void def initialize(name, condition = nil, &blk) @name = name @execution = if blk @@ -38,6 +39,7 @@ def initialize(name, condition = nil, &blk) end end + # @rbs (Selenium::WebDriver::Support::Guards::Guard) -> bool def satisfied?(guard) list = Array(guard.guarded[@name]) diff --git a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb index 99ce2fa689e9e..96b1c375a770f 100644 --- a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb +++ b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb @@ -321,7 +321,7 @@ module WebDriver describe '#scroll_by' do it 'scrolls by given amount', - exclude: {driver: :firefox, reason: 'inconsistent behavior between versions'} do + exclude: {driver: :chrome, reason: 'inconsistent behavior between versions'} do driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') footer = driver.find_element(tag_name: 'footer') delta_y = footer.rect.y.round diff --git a/rb/spec/integration/selenium/webdriver/spec_helper.rb b/rb/spec/integration/selenium/webdriver/spec_helper.rb index 751c6f185634e..dace160154833 100644 --- a/rb/spec/integration/selenium/webdriver/spec_helper.rb +++ b/rb/spec/integration/selenium/webdriver/spec_helper.rb @@ -19,6 +19,7 @@ require 'rubygems' require 'time' +require 'rbs-trace' require 'rspec' require 'selenium-webdriver' @@ -30,6 +31,7 @@ GlobalTestEnv = WebDriver::SpecSupport::TestEnvironment.new class SeleniumTestListener + # @rbs (RSpec::Core::Notifications::ExampleNotification) -> nil def example_finished(notification) exception = notification.example.exception assertion_failed = exception && @@ -50,13 +52,18 @@ def example_finished(notification) c.include(WebDriver::SpecSupport::Helpers) + trace = RBS::Trace.new + c.before(:suite) do GlobalTestEnv.remote_server.start if GlobalTestEnv.driver == :remote && ENV['WD_REMOTE_URL'].nil? GlobalTestEnv.print_env + trace.enable end c.after(:suite) do GlobalTestEnv.quit_driver + trace.disable + trace.save_comments end c.filter_run_when_matching :focus diff --git a/rb/spec/integration/selenium/webdriver/spec_support/helpers.rb b/rb/spec/integration/selenium/webdriver/spec_support/helpers.rb index 40e62f73bc2c8..39f0c29b48c71 100644 --- a/rb/spec/integration/selenium/webdriver/spec_support/helpers.rb +++ b/rb/spec/integration/selenium/webdriver/spec_support/helpers.rb @@ -21,10 +21,12 @@ module Selenium module WebDriver module SpecSupport module Helpers + # @rbs () -> Selenium::WebDriver::Chrome::Driver def driver GlobalTestEnv.driver_instance end + # @rbs (*untyped, **untyped) -> bool def reset_driver!(...) GlobalTestEnv.reset_driver!(...) end @@ -37,6 +39,7 @@ def create_driver!(...) GlobalTestEnv.create_driver!(...) end + # @rbs (String) -> String def url_for(filename) GlobalTestEnv.url_for filename end diff --git a/rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb b/rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb index d141d536b9c37..0143304494ef1 100644 --- a/rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb +++ b/rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb @@ -25,6 +25,7 @@ module SpecSupport class RackServer START_TIMEOUT = 30 + # @rbs (String, Integer) -> void def initialize(path, port) @path = path @app = TestApp.new(path) @@ -33,6 +34,7 @@ def initialize(path, port) @port = port end + # @rbs () -> void def start if Platform.jruby? || Platform.windows? || Platform.truffleruby? start_threaded @@ -49,6 +51,7 @@ def run handler.run @app, Host: @host, Port: @port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) end + # @rbs (String) -> String def where_is(file) "http://#{@host}:#{@port}/#{file}" end @@ -86,6 +89,7 @@ def load_handler(handler) false end + # @rbs () -> Integer def start_forked @pid = fork { run } end @@ -99,6 +103,7 @@ def start_threaded class TestApp BASIC_AUTH_CREDENTIALS = %w[test test].freeze + # @rbs (String) -> void def initialize(file_root) @static = Rack::File.new(file_root) end diff --git a/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb b/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb index 517a10ce1e909..22a3b49076e27 100644 --- a/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb +++ b/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb @@ -49,6 +49,7 @@ def print_env puts "\n" end + # @rbs () -> Symbol def browser if driver == :remote ENV.fetch('WD_REMOTE_BROWSER', 'chrome').tr('-', '_').to_sym @@ -57,10 +58,12 @@ def browser end end + # @rbs (*untyped, **untyped) -> bool def driver_instance(...) @driver_instance || create_driver!(...) end + # @rbs (?time: Integer, **Hash[untyped, untyped]) -> bool def reset_driver!(time: 0, **opts, &block) # do not reset if the test was marked skipped return if opts.delete(:example)&.metadata&.fetch(:skip, nil) @@ -70,6 +73,7 @@ def reset_driver!(time: 0, **opts, &block) driver_instance(**opts, &block) end + # @rbs () -> void def quit_driver @driver_instance&.quit rescue StandardError @@ -78,6 +82,7 @@ def quit_driver @driver_instance = nil end + # @rbs () -> Selenium::WebDriver::SpecSupport::RackServer def app_server @app_server ||= begin app_server = RackServer.new(root.join('common/src/web').to_s, random_port) @@ -115,6 +120,7 @@ def bazel_java File.expand_path(File.read(File.expand_path(ENV.fetch('WD_BAZEL_JAVA_LOCATION'))).chomp) end + # @rbs () -> bool def rbe? Dir.pwd.start_with?('/mnt/engflow') end @@ -153,16 +159,19 @@ def quit @driver_instance = @app_server = @remote_server = nil end + # @rbs (String) -> String def url_for(filename) app_server.where_is filename end + # @rbs () -> Pathname def root # prefer #realpath over #expand_path to avoid problems with UNC # see https://bugs.ruby-lang.org/issues/13515 @root ||= Pathname.new('../../../../../../../').realpath(__FILE__) end + # @rbs (?listener: nil, **Hash[untyped, untyped]) -> bool def create_driver!(listener: nil, **opts, &block) check_for_previous_error @@ -190,6 +199,7 @@ def create_driver!(listener: nil, **opts, &block) private + # @rbs (**Hash[untyped, untyped]) -> Selenium::WebDriver::Chrome::Options def build_options(**opts) options_method = :"#{browser}_options" if private_methods.include?(options_method) @@ -215,6 +225,7 @@ def current_env class DriverInstantiationError < StandardError end + # @rbs () -> void def check_for_previous_error return unless @create_driver_error && @create_driver_error_count >= MAX_ERRORS @@ -230,6 +241,7 @@ def remote_driver(**opts) WebDriver::Driver.for(:remote, url: url, **opts) end + # @rbs (?service: nil, **Selenium::WebDriver::Chrome::Options?) -> Selenium::WebDriver::Chrome::Driver def chrome_driver(service: nil, **opts) service ||= WebDriver::Service.chrome service.args << '--disable-build-check' if ENV['DISABLE_BUILD_CHECK'] @@ -265,6 +277,7 @@ def safari_preview_driver(**opts) WebDriver::Driver.for(:safari, service: service, **opts) end + # @rbs (?args: Array[untyped], **Hash[untyped, untyped]) -> Selenium::WebDriver::Chrome::Options def chrome_options(args: [], **opts) opts[:browser_version] = 'stable' if WebDriver::Platform.windows? opts[:web_socket_url] = true if ENV['WEBDRIVER_BIDI'] && !opts.key?(:web_socket_url) @@ -303,6 +316,7 @@ def safari_preview_options(**opts) WebDriver::Options.safari(**opts) end + # @rbs () -> Integer def random_port addr = Socket.getaddrinfo(Platform.localhost, 0, Socket::AF_INET, Socket::SOCK_STREAM) addr = Socket.pack_sockaddr_in(0, addr[0][3]) From 289760c8c17a9ffcde838f2019d0f925ca795844 Mon Sep 17 00:00:00 2001 From: aguspe Date: Fri, 2 May 2025 22:21:53 +0200 Subject: [PATCH 3/6] Add RBS comments --- rb/lib/selenium/devtools.rb | 1 + rb/lib/selenium/server.rb | 1 + rb/lib/selenium/webdriver/atoms.rb | 3 + rb/lib/selenium/webdriver/bidi.rb | 8 + .../webdriver/bidi/browsing_context.rb | 9 + rb/lib/selenium/webdriver/bidi/log_handler.rb | 4 + .../selenium/webdriver/bidi/log_inspector.rb | 9 + rb/lib/selenium/webdriver/bidi/network.rb | 12 + .../bidi/network/intercepted_auth.rb | 3 + .../bidi/network/intercepted_item.rb | 2 + .../bidi/network/intercepted_request.rb | 6 + .../bidi/network/intercepted_response.rb | 7 + rb/lib/selenium/webdriver/bidi/session.rb | 3 + rb/lib/selenium/webdriver/bidi/struct.rb | 1 + rb/lib/selenium/webdriver/chrome/driver.rb | 1 + rb/lib/selenium/webdriver/chrome/options.rb | 1 + rb/lib/selenium/webdriver/chromium/driver.rb | 2 + .../selenium/webdriver/chromium/features.rb | 7 + rb/lib/selenium/webdriver/chromium/profile.rb | 4 + .../webdriver/common/action_builder.rb | 11 + rb/lib/selenium/webdriver/common/alert.rb | 5 + .../webdriver/common/child_process.rb | 3 + rb/lib/selenium/webdriver/common/driver.rb | 20 ++ .../driver_extensions/downloads_files.rb | 1 + .../driver_extensions/full_page_screenshot.rb | 2 + .../common/driver_extensions/has_addons.rb | 2 + .../driver_extensions/has_authentication.rb | 3 + .../common/driver_extensions/has_bidi.rb | 1 + .../common/driver_extensions/has_casting.rb | 1 + .../common/driver_extensions/has_context.rb | 2 + .../common/driver_extensions/has_devtools.rb | 1 + .../driver_extensions/has_fedcm_dialog.rb | 4 + .../driver_extensions/has_file_downloads.rb | 4 + .../driver_extensions/has_log_events.rb | 7 + .../common/driver_extensions/has_logs.rb | 1 + .../has_network_conditions.rb | 3 + .../has_network_interception.rb | 1 + .../driver_extensions/has_permissions.rb | 2 + .../driver_extensions/has_pinned_scripts.rb | 3 + .../driver_extensions/has_session_id.rb | 1 + .../common/driver_extensions/prints_page.rb | 2 + .../common/driver_extensions/uploads_files.rb | 1 + rb/lib/selenium/webdriver/common/element.rb | 27 ++ rb/lib/selenium/webdriver/common/error.rb | 2 + .../webdriver/common/fedcm/account.rb | 1 + .../selenium/webdriver/common/fedcm/dialog.rb | 8 + .../selenium/webdriver/common/file_reaper.rb | 2 + .../common/interactions/input_device.rb | 5 + .../common/interactions/interaction.rb | 1 + .../common/interactions/interactions.rb | 4 + .../common/interactions/key_actions.rb | 5 + .../common/interactions/key_input.rb | 3 + .../webdriver/common/interactions/pause.rb | 3 + .../common/interactions/pointer_actions.rb | 15 + .../interactions/pointer_event_properties.rb | 2 + .../common/interactions/pointer_input.rb | 6 + .../common/interactions/pointer_move.rb | 3 + .../common/interactions/pointer_press.rb | 5 + .../webdriver/common/interactions/scroll.rb | 3 + .../common/interactions/scroll_origin.rb | 3 + .../common/interactions/typing_interaction.rb | 4 + .../common/interactions/wheel_actions.rb | 6 + .../common/interactions/wheel_input.rb | 2 + rb/lib/selenium/webdriver/common/keys.rb | 3 + rb/lib/selenium/webdriver/common/log_entry.rb | 1 + rb/lib/selenium/webdriver/common/logger.rb | 2 + rb/lib/selenium/webdriver/common/logs.rb | 3 + rb/lib/selenium/webdriver/common/manager.rb | 12 + .../selenium/webdriver/common/navigation.rb | 3 + rb/lib/selenium/webdriver/common/network.rb | 7 + rb/lib/selenium/webdriver/common/options.rb | 2 + rb/lib/selenium/webdriver/common/platform.rb | 1 + .../webdriver/common/profile_helper.rb | 2 + rb/lib/selenium/webdriver/common/script.rb | 4 + .../webdriver/common/search_context.rb | 4 + .../webdriver/common/selenium_manager.rb | 2 + rb/lib/selenium/webdriver/common/service.rb | 3 + .../selenium/webdriver/common/shadow_root.rb | 3 + .../webdriver/common/takes_screenshot.rb | 2 + .../webdriver/common/target_locator.rb | 8 + rb/lib/selenium/webdriver/common/timeouts.rb | 7 + .../virtual_authenticator/credential.rb | 7 + .../virtual_authenticator.rb | 8 + .../virtual_authenticator_options.rb | 2 + rb/lib/selenium/webdriver/common/wait.rb | 3 + .../webdriver/common/websocket_connection.rb | 16 + rb/lib/selenium/webdriver/common/window.rb | 10 + rb/lib/selenium/webdriver/common/zipper.rb | 5 + rb/lib/selenium/webdriver/devtools.rb | 6 + .../webdriver/devtools/console_event.rb | 1 + .../webdriver/devtools/exception_event.rb | 1 + .../webdriver/devtools/mutation_event.rb | 1 + .../webdriver/devtools/network_interceptor.rb | 12 + .../webdriver/devtools/pinned_script.rb | 4 + rb/lib/selenium/webdriver/devtools/request.rb | 3 + .../selenium/webdriver/devtools/response.rb | 3 + rb/lib/selenium/webdriver/edge.rb | 1 + rb/lib/selenium/webdriver/edge/driver.rb | 3 + rb/lib/selenium/webdriver/edge/features.rb | 2 + rb/lib/selenium/webdriver/edge/options.rb | 2 + rb/lib/selenium/webdriver/edge/service.rb | 1 + rb/lib/selenium/webdriver/firefox.rb | 1 + rb/lib/selenium/webdriver/firefox/driver.rb | 2 + rb/lib/selenium/webdriver/firefox/features.rb | 7 + rb/lib/selenium/webdriver/firefox/options.rb | 4 + rb/lib/selenium/webdriver/firefox/profile.rb | 10 + rb/lib/selenium/webdriver/firefox/service.rb | 1 + rb/lib/selenium/webdriver/firefox/util.rb | 1 + .../selenium/webdriver/remote/bidi_bridge.rb | 8 + rb/lib/selenium/webdriver/remote/bridge.rb | 87 ++++++ .../remote/bridge/locator_converter.rb | 2 + .../selenium/webdriver/remote/capabilities.rb | 4 + rb/lib/selenium/webdriver/remote/driver.rb | 4 + rb/lib/selenium/webdriver/remote/features.rb | 8 + rb/lib/selenium/webdriver/remote/response.rb | 1 + .../support/abstract_event_listener.rb | 2 + rb/lib/selenium/webdriver/support/escaper.rb | 1 + .../webdriver/support/event_firing_bridge.rb | 5 + .../webdriver/support/guards/guard.rb | 1 + .../webdriver/support/relative_locator.rb | 2 + rb/lib/selenium/webdriver/support/select.rb | 22 ++ rb/rbs_collection.lock.yaml | 52 ++++ rb/sig/lib/selenium/webdriver.rbs | 35 +-- rb/sig/lib/selenium/webdriver/chrome.rbs | 14 +- .../lib/selenium/webdriver/chrome/driver.rbs | 18 +- .../selenium/webdriver/chrome/features.rbs | 17 +- .../lib/selenium/webdriver/chrome/options.rbs | 18 +- .../lib/selenium/webdriver/chrome/service.rbs | 20 +- .../selenium/webdriver/chromium/options.rbs | 56 +--- .../webdriver/common/child_process.rbs | 53 +--- .../lib/selenium/webdriver/common/driver.rbs | 82 +---- .../webdriver/common/driver_finder.rbs | 27 +- .../lib/selenium/webdriver/common/error.rbs | 110 +------ .../webdriver/common/local_driver.rbs | 12 +- .../lib/selenium/webdriver/common/logger.rbs | 45 +-- .../selenium/webdriver/common/navigation.rbs | 16 +- .../lib/selenium/webdriver/common/options.rbs | 74 ++--- .../selenium/webdriver/common/platform.rbs | 63 +--- .../selenium/webdriver/common/port_prober.rbs | 12 +- .../webdriver/common/selenium_manager.rbs | 31 +- .../lib/selenium/webdriver/common/service.rbs | 66 +--- .../webdriver/common/service_manager.rbs | 62 +--- .../selenium/webdriver/common/socket_lock.rbs | 28 +- .../webdriver/common/socket_poller.rbs | 38 +-- rb/sig/lib/selenium/webdriver/common/wait.rbs | 26 +- .../lib/selenium/webdriver/remote/bridge.rbs | 286 ++---------------- .../webdriver/remote/capabilities.rbs | 73 +---- .../selenium/webdriver/remote/http/common.rbs | 46 +-- .../webdriver/remote/http/default.rbs | 59 ++-- .../selenium/webdriver/remote/response.rbs | 39 +-- .../lib/selenium/webdriver/support/guards.rbs | 46 +-- .../webdriver/support/guards/guard.rbs | 41 +-- .../support/guards/guard_condition.rbs | 23 +- .../selenium/webdriver/spec_helper.rb | 1 + 154 files changed, 929 insertions(+), 1268 deletions(-) diff --git a/rb/lib/selenium/devtools.rb b/rb/lib/selenium/devtools.rb index 4df984b3ea30d..866cf68dba7c3 100644 --- a/rb/lib/selenium/devtools.rb +++ b/rb/lib/selenium/devtools.rb @@ -22,6 +22,7 @@ module DevTools class << self attr_accessor :version + # @rbs () -> void def load_version require "selenium/devtools/v#{@version}" rescue LoadError diff --git a/rb/lib/selenium/server.rb b/rb/lib/selenium/server.rb index ef2b05e99f199..b4d802cace12b 100644 --- a/rb/lib/selenium/server.rb +++ b/rb/lib/selenium/server.rb @@ -215,6 +215,7 @@ def stop @log_file&.close end + # @rbs () -> String def webdriver_url "http://#{@host}:#{@port}/wd/hub" end diff --git a/rb/lib/selenium/webdriver/atoms.rb b/rb/lib/selenium/webdriver/atoms.rb index fac103f669b9f..b036b3eb74621 100644 --- a/rb/lib/selenium/webdriver/atoms.rb +++ b/rb/lib/selenium/webdriver/atoms.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver module Atoms + # @rbs (Symbol) -> String def atom_script(function_name) format("/* #{function_name} */return (%s).apply(null, arguments)", atom: read_atom(function_name)) @@ -27,10 +28,12 @@ def atom_script(function_name) private + # @rbs (Symbol) -> String def read_atom(function) File.read(File.expand_path("../atoms/#{function}.js", __FILE__)) end + # @rbs (Symbol, *Selenium::WebDriver::Element | String | Hash[untyped, untyped]) -> (String | Array[untyped]) def execute_atom(function_name, *arguments) execute_script(atom_script(function_name), *arguments) end diff --git a/rb/lib/selenium/webdriver/bidi.rb b/rb/lib/selenium/webdriver/bidi.rb index 4c8ca37b4f8d2..a27925af7dedf 100644 --- a/rb/lib/selenium/webdriver/bidi.rb +++ b/rb/lib/selenium/webdriver/bidi.rb @@ -31,30 +31,37 @@ class BiDi autoload :InterceptedAuth, 'selenium/webdriver/bidi/network/intercepted_auth' autoload :InterceptedItem, 'selenium/webdriver/bidi/network/intercepted_item' + # @rbs (url: String) -> void def initialize(url:) @ws = WebSocketConnection.new(url: url) end + # @rbs () -> nil def close @ws.close end + # @rbs () -> Hash[untyped, untyped] def callbacks @ws.callbacks end + # @rbs (String) -> void def add_callback(event, &block) @ws.add_callback(event, &block) end + # @rbs (String, Integer) -> void def remove_callback(event, id) @ws.remove_callback(event, id) end + # @rbs () -> Selenium::WebDriver::BiDi::Session def session @session ||= Session.new(self) end + # @rbs (String, **String | String | Integer | String | bool) -> Hash[untyped, untyped] def send_cmd(method, **params) data = {method: method, params: params.compact} message = @ws.send_cmd(**data) @@ -63,6 +70,7 @@ def send_cmd(method, **params) message['result'] end + # @rbs (Hash[untyped, untyped]) -> String def error_message(message) "#{message['error']}: #{message['message']}\n#{message['stacktrace']}" end diff --git a/rb/lib/selenium/webdriver/bidi/browsing_context.rb b/rb/lib/selenium/webdriver/bidi/browsing_context.rb index ed59d23b381e8..d2cacbd8be7c4 100644 --- a/rb/lib/selenium/webdriver/bidi/browsing_context.rb +++ b/rb/lib/selenium/webdriver/bidi/browsing_context.rb @@ -32,6 +32,7 @@ class BrowsingContext }.freeze # TODO: store current window handle in bridge object instead of always calling it + # @rbs (Selenium::WebDriver::Remote::BiDiBridge) -> void def initialize(bridge) @bridge = bridge @bidi = @bridge.bidi @@ -44,6 +45,7 @@ def initialize(bridge) # @param url [String] The URL to navigate to. # @param context_id [String, NilClass] The ID of the browsing context to navigate in. # Defaults to the window handle of the current context. + # @rbs (String, ?context_id: nil) -> Hash[untyped, untyped] def navigate(url, context_id: nil) context_id ||= @bridge.window_handle @bidi.send_cmd('browsingContext.navigate', context: context_id, url: url, wait: @readiness) @@ -55,6 +57,7 @@ def navigate(url, context_id: nil) # Positive values go forwards, negative values go backwards. # @param context_id [String, NilClass] The ID of the context to traverse. # Defaults to the window handle of the current context. + # @rbs (Integer, ?context_id: nil) -> Hash[untyped, untyped] def traverse_history(delta, context_id: nil) context_id ||= @bridge.window_handle @bidi.send_cmd('browsingContext.traverseHistory', context: context_id, delta: delta) @@ -65,6 +68,7 @@ def traverse_history(delta, context_id: nil) # Defaults to the window handle of the current context. # @param [Boolean] ignore_cache Whether to bypass the cache when reloading. # Defaults to false. + # @rbs (?context_id: nil, ?ignore_cache: bool) -> Hash[untyped, untyped] def reload(context_id: nil, ignore_cache: false) context_id ||= @bridge.window_handle params = {context: context_id, ignore_cache: ignore_cache, wait: @readiness} @@ -75,6 +79,7 @@ def reload(context_id: nil, ignore_cache: false) # # @param [String] context_id The ID of the context to close. # Defaults to the window handle of the current context. + # @rbs (?context_id: String) -> void def close(context_id: nil) context_id ||= @bridge.window_handle @bidi.send_cmd('browsingContext.close', context: context_id) @@ -88,6 +93,7 @@ def close(context_id: nil) # Defaults to the current window handle. # # @return [String] The context ID of the created browsing context. + # @rbs (?type: nil, ?context_id: nil) -> String def create(type: nil, context_id: nil) type ||= :window context_id ||= @bridge.window_handle @@ -95,16 +101,19 @@ def create(type: nil, context_id: nil) result['context'] end + # @rbs (?context_id: nil, ?width: Integer, ?height: Integer, ?device_pixel_ratio: Float) -> void def set_viewport(context_id: nil, width: nil, height: nil, device_pixel_ratio: nil) context_id ||= @bridge.window_handle params = {context: context_id, viewport: {width:, height:}, device_pixel_ratio:} @bidi.send_cmd('browsingContext.setViewport', **params) end + # @rbs (String, ?accept: bool, ?text: nil | String) -> void def handle_user_prompt(context_id, accept: true, text: nil) @bidi.send_cmd('browsingContext.handleUserPrompt', context: context_id, accept: accept, text: text) end + # @rbs (?context_id: nil) -> void def activate(context_id: nil) context_id ||= @bridge.window_handle @bidi.send_cmd('browsingContext.activate', context: context_id) diff --git a/rb/lib/selenium/webdriver/bidi/log_handler.rb b/rb/lib/selenium/webdriver/bidi/log_handler.rb index 29b3d4dcab0d9..a213e3c93211c 100644 --- a/rb/lib/selenium/webdriver/bidi/log_handler.rb +++ b/rb/lib/selenium/webdriver/bidi/log_handler.rb @@ -24,6 +24,7 @@ class LogHandler ConsoleLogEntry = BiDi::Struct.new(:level, :text, :timestamp, :stack_trace, :type, :source, :method, :args) JavaScriptLogEntry = BiDi::Struct.new(:level, :text, :timestamp, :stack_trace, :type, :source) + # @rbs (Selenium::WebDriver::BiDi) -> void def initialize(bidi) @bidi = bidi @log_entry_subscribed = false @@ -31,6 +32,7 @@ def initialize(bidi) # @return [int] id of the handler # steep:ignore:start + # @rbs (String) -> Integer def add_message_handler(type) subscribe_log_entry unless @log_entry_subscribed @bidi.add_callback('log.entryAdded') do |params| @@ -43,6 +45,7 @@ def add_message_handler(type) # steep:ignore:end # @param [int] id of the handler previously added + # @rbs (Integer) -> nil def remove_message_handler(id) @bidi.remove_callback('log.entryAdded', id) unsubscribe_log_entry if @log_entry_subscribed && @bidi.callbacks['log.entryAdded'].empty? @@ -50,6 +53,7 @@ def remove_message_handler(id) private + # @rbs () -> bool def subscribe_log_entry @bidi.session.subscribe('log.entryAdded') @log_entry_subscribed = true diff --git a/rb/lib/selenium/webdriver/bidi/log_inspector.rb b/rb/lib/selenium/webdriver/bidi/log_inspector.rb index 133666cec0f01..3ac9e74ec5ae3 100644 --- a/rb/lib/selenium/webdriver/bidi/log_inspector.rb +++ b/rb/lib/selenium/webdriver/bidi/log_inspector.rb @@ -40,6 +40,7 @@ class LogInspector WARNING: 'warning' }.freeze + # @rbs (Selenium::WebDriver::Chrome::Driver, ?nil) -> void def initialize(driver, browsing_context_ids = nil) WebDriver.logger.deprecate('LogInspector class', 'Script class with driver.script', @@ -54,6 +55,7 @@ def initialize(driver, browsing_context_ids = nil) @bidi.session.subscribe('log.entryAdded', browsing_context_ids) end + # @rbs (?Selenium::WebDriver::BiDi::FilterBy?) -> void def on_console_entry(filter_by = nil, &block) check_valid_filter(filter_by) @@ -63,6 +65,7 @@ def on_console_entry(filter_by = nil, &block) end end + # @rbs (?Selenium::WebDriver::BiDi::FilterBy?) -> void def on_javascript_log(filter_by = nil, &block) check_valid_filter(filter_by) @@ -72,6 +75,7 @@ def on_javascript_log(filter_by = nil, &block) end end + # @rbs () -> void def on_javascript_exception(&block) on_log do |params| type = params['type'] @@ -79,6 +83,7 @@ def on_javascript_exception(&block) end end + # @rbs (?Selenium::WebDriver::BiDi::FilterBy?) -> Integer? def on_log(filter_by = nil, &block) unless filter_by.nil? check_valid_filter(filter_by) @@ -94,17 +99,20 @@ def on_log(filter_by = nil, &block) private + # @rbs (Symbol) -> Integer def on(event, &block) event = EVENTS[event] if event.is_a?(Symbol) @bidi.add_callback("log.#{event}", &block) end + # @rbs (Selenium::WebDriver::BiDi::FilterBy?) -> void def check_valid_filter(filter_by) return if filter_by.nil? || filter_by.instance_of?(FilterBy) raise "Pass valid FilterBy object. Received: #{filter_by.inspect}" end + # @rbs (Hash[untyped, untyped], Selenium::WebDriver::BiDi::FilterBy?) -> Array[untyped]? def console_log_events(params, filter_by) event = ConsoleLogEntry.new( level: params['level'], @@ -125,6 +133,7 @@ def console_log_events(params, filter_by) yield(event) end + # @rbs (Hash[untyped, untyped], Selenium::WebDriver::BiDi::FilterBy?) -> Selenium::WebDriver::BiDi::JavascriptLogEntry? def javascript_log_events(params, filter_by) event = JavascriptLogEntry.new( level: params['level'], diff --git a/rb/lib/selenium/webdriver/bidi/network.rb b/rb/lib/selenium/webdriver/bidi/network.rb index 26f62f64a22dc..18d78a1b2ecfb 100644 --- a/rb/lib/selenium/webdriver/bidi/network.rb +++ b/rb/lib/selenium/webdriver/bidi/network.rb @@ -36,10 +36,12 @@ class Network auth_required: 'authRequired' }.freeze + # @rbs (Selenium::WebDriver::BiDi) -> void def initialize(bidi) @bidi = bidi end + # @rbs (?phases: Array[untyped], ?contexts: nil, ?url_patterns: Array[untyped], ?pattern_type: nil | Symbol) -> Hash[untyped, untyped] def add_intercept(phases: [], contexts: nil, url_patterns: nil, pattern_type: :string) url_patterns = url_patterns && pattern_type ? UrlPattern.format_pattern(url_patterns, pattern_type) : nil @bidi.send_cmd('network.addIntercept', @@ -48,10 +50,12 @@ def add_intercept(phases: [], contexts: nil, url_patterns: nil, pattern_type: :s urlPatterns: url_patterns) end + # @rbs (String) -> void def remove_intercept(intercept) @bidi.send_cmd('network.removeIntercept', intercept: intercept) end + # @rbs (String, String, String) -> Hash[untyped, untyped] def continue_with_auth(request_id, username, password) @bidi.send_cmd( 'network.continueWithAuth', @@ -65,6 +69,7 @@ def continue_with_auth(request_id, username, password) ) end + # @rbs (String) -> Hash[untyped, untyped] def continue_without_auth(request_id) @bidi.send_cmd( 'network.continueWithAuth', @@ -73,6 +78,7 @@ def continue_without_auth(request_id) ) end + # @rbs (String) -> Hash[untyped, untyped] def cancel_auth(request_id) @bidi.send_cmd( 'network.continueWithAuth', @@ -81,6 +87,7 @@ def cancel_auth(request_id) ) end + # @rbs (**(String | Array[untyped])? | String | Hash[untyped, untyped] | Array[untyped]) -> Hash[untyped, untyped]? def continue_request(**args) @bidi.send_cmd( 'network.continueRequest', @@ -93,6 +100,7 @@ def continue_request(**args) ) end + # @rbs (String) -> Hash[untyped, untyped]? def fail_request(request_id) @bidi.send_cmd( 'network.failRequest', @@ -100,6 +108,7 @@ def fail_request(request_id) ) end + # @rbs (**(String | Array[untyped])? | (String | Array[untyped] | Hash[untyped, untyped])?) -> Hash[untyped, untyped]? def continue_response(**args) @bidi.send_cmd( 'network.continueResponse', @@ -112,6 +121,7 @@ def continue_response(**args) ) end + # @rbs (**(String | Array[untyped] | Hash[untyped, untyped] | Integer)?) -> Hash[untyped, untyped] def provide_response(**args) @bidi.send_cmd( 'network.provideResponse', @@ -124,10 +134,12 @@ def provide_response(**args) ) end + # @rbs (String, *String) -> Hash[untyped, untyped] def set_cache_behavior(behavior, *contexts) @bidi.send_cmd('network.setCacheBehavior', cacheBehavior: behavior, contexts: contexts) end + # @rbs (Symbol) -> Hash[untyped, untyped] def on(event, &block) event = EVENTS[event] if event.is_a?(Symbol) @bidi.add_callback(event, &block) diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_auth.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_auth.rb index 71c5d7bcac785..d45ed3ecdbec4 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_auth.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_auth.rb @@ -21,14 +21,17 @@ module Selenium module WebDriver class BiDi class InterceptedAuth < InterceptedItem + # @rbs (String, String) -> Hash[untyped, untyped] def authenticate(username, password) network.continue_with_auth(id, username, password) end + # @rbs () -> Hash[untyped, untyped] def skip network.continue_without_auth(id) end + # @rbs () -> Hash[untyped, untyped] def cancel network.cancel_auth(id) end diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_item.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_item.rb index 1f7445ebbe78b..30730e43241aa 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_item.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_item.rb @@ -23,11 +23,13 @@ class BiDi class InterceptedItem attr_reader :network, :request + # @rbs (Selenium::WebDriver::BiDi::Network, Hash[untyped, untyped]) -> void def initialize(network, request) @network = network @request = request end + # @rbs () -> String def id @id ||= @request['request'] end diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb index ad2ef94295092..2e9b3a11fea02 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb @@ -27,6 +27,7 @@ class InterceptedRequest < InterceptedItem attr_accessor :method, :url attr_reader :body + # @rbs (Selenium::WebDriver::BiDi::Network, Hash[untyped, untyped]) -> void def initialize(network, request) super @method = nil @@ -34,6 +35,7 @@ def initialize(network, request) @body = nil end + # @rbs () -> Hash[untyped, untyped]? def continue network.continue_request( id: id, @@ -45,10 +47,12 @@ def continue ) end + # @rbs () -> Hash[untyped, untyped]? def fail network.fail_request(id) end + # @rbs (Hash[untyped, untyped]) -> void def body=(value) @body = { type: 'string', @@ -56,10 +60,12 @@ def body=(value) } end + # @rbs () -> Selenium::WebDriver::BiDi::Headers def headers @headers ||= Headers.new end + # @rbs (?Hash[untyped, untyped]) -> Selenium::WebDriver::BiDi::Cookies def cookies(cookies = {}) @cookies ||= Cookies.new(cookies) end diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb index 08e4b9c84a715..3a39dcbba0f90 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb @@ -28,6 +28,7 @@ class InterceptedResponse < InterceptedItem attr_accessor :reason, :status attr_reader :body + # @rbs (Selenium::WebDriver::BiDi::Network, Hash[untyped, untyped]) -> void def initialize(network, request) super @reason = nil @@ -35,6 +36,7 @@ def initialize(network, request) @body = nil end + # @rbs () -> Hash[untyped, untyped]? def continue network.continue_response( id: id, @@ -46,6 +48,7 @@ def continue ) end + # @rbs () -> Hash[untyped, untyped] def provide_response network.provide_response( id: id, @@ -57,18 +60,22 @@ def provide_response ) end + # @rbs (?username: nil, ?password: nil) -> Selenium::WebDriver::BiDi::Credentials def credentials(username: nil, password: nil) @credentials ||= Credentials.new(username: username, password: password) end + # @rbs () -> Selenium::WebDriver::BiDi::Headers def headers @headers ||= Headers.new end + # @rbs (?Hash[untyped, untyped]) -> Selenium::WebDriver::BiDi::Cookies def cookies(cookies = {}) @cookies ||= Cookies.new(cookies) end + # @rbs (String) -> void def body=(value) @body = { type: 'string', diff --git a/rb/lib/selenium/webdriver/bidi/session.rb b/rb/lib/selenium/webdriver/bidi/session.rb index d3ae6792c46d9..8e56cf631646d 100644 --- a/rb/lib/selenium/webdriver/bidi/session.rb +++ b/rb/lib/selenium/webdriver/bidi/session.rb @@ -23,15 +23,18 @@ class BiDi class Session Status = Struct.new(:ready, :message) + # @rbs (Selenium::WebDriver::BiDi) -> void def initialize(bidi) @bidi = bidi end + # @rbs () -> Selenium::WebDriver::BiDi::Session::Status? def status status = @bidi.send_cmd('session.status') Status.new(**status) end + # @rbs (String, ?nil) -> Hash[untyped, untyped] def subscribe(events, browsing_contexts = nil) opts = {events: Array(events)} opts[:browsing_contexts] = Array(browsing_contexts) if browsing_contexts diff --git a/rb/lib/selenium/webdriver/bidi/struct.rb b/rb/lib/selenium/webdriver/bidi/struct.rb index 951f09b8ad03a..4217c900b2298 100644 --- a/rb/lib/selenium/webdriver/bidi/struct.rb +++ b/rb/lib/selenium/webdriver/bidi/struct.rb @@ -22,6 +22,7 @@ module WebDriver class BiDi class Struct < ::Struct class << self + # @rbs (*Symbol) -> Class def new(*args, &block) super do define_method(:initialize) do |**kwargs| diff --git a/rb/lib/selenium/webdriver/chrome/driver.rb b/rb/lib/selenium/webdriver/chrome/driver.rb index 91d6b18135a31..d9c981edcb91d 100644 --- a/rb/lib/selenium/webdriver/chrome/driver.rb +++ b/rb/lib/selenium/webdriver/chrome/driver.rb @@ -43,6 +43,7 @@ def browser private + # @rbs () -> String def devtools_address "http://#{capabilities['goog:chromeOptions']['debuggerAddress']}" end diff --git a/rb/lib/selenium/webdriver/chrome/options.rb b/rb/lib/selenium/webdriver/chrome/options.rb index 2ac91c39505cd..c30e69263e0d7 100644 --- a/rb/lib/selenium/webdriver/chrome/options.rb +++ b/rb/lib/selenium/webdriver/chrome/options.rb @@ -28,6 +28,7 @@ class Options < Chromium::Options private + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def enable_logging(browser_options) browser_options['goog:loggingPrefs'] = @logging_prefs end diff --git a/rb/lib/selenium/webdriver/chromium/driver.rb b/rb/lib/selenium/webdriver/chromium/driver.rb index aa6af16aa0433..8740f51cd9477 100644 --- a/rb/lib/selenium/webdriver/chromium/driver.rb +++ b/rb/lib/selenium/webdriver/chromium/driver.rb @@ -44,6 +44,7 @@ class Driver < WebDriver::Driver protected + # @rbs () -> String def devtools_url uri = URI(devtools_address) response = Net::HTTP.get(uri.hostname, '/json/version', uri.port) @@ -51,6 +52,7 @@ def devtools_url JSON.parse(response)['webSocketDebuggerUrl'] end + # @rbs () -> Integer def devtools_version Integer(capabilities.browser_version.split('.').first) end diff --git a/rb/lib/selenium/webdriver/chromium/features.rb b/rb/lib/selenium/webdriver/chromium/features.rb index ad19eb8c48490..e10af3aeab8f0 100644 --- a/rb/lib/selenium/webdriver/chromium/features.rb +++ b/rb/lib/selenium/webdriver/chromium/features.rb @@ -35,6 +35,7 @@ def launch_app(id) execute :launch_app, {}, {id: id} end + # @rbs () -> Array[untyped] def cast_sinks execute :get_cast_sinks end @@ -59,18 +60,22 @@ def stop_casting(name) execute :stop_casting, {}, {sinkName: name} end + # @rbs (String, String) -> nil def set_permission(name, value) execute :set_permission, {}, {descriptor: {name: name}, state: value} end + # @rbs () -> Hash[untyped, untyped]? def network_conditions execute :get_network_conditions end + # @rbs (Hash[untyped, untyped]) -> nil def network_conditions=(conditions) execute :set_network_conditions, {}, {network_conditions: conditions} end + # @rbs () -> nil def delete_network_conditions execute :delete_network_conditions end @@ -80,11 +85,13 @@ def send_command(command_params) execute :send_command, {}, command_params end + # @rbs () -> Array[untyped] def available_log_types types = execute :get_available_log_types Array(types).map(&:to_sym) end + # @rbs (Symbol) -> Array[untyped] def log(type) data = execute :get_log, {}, {type: type.to_s} diff --git a/rb/lib/selenium/webdriver/chromium/profile.rb b/rb/lib/selenium/webdriver/chromium/profile.rb index 891df8e2a98aa..4e98adc99b8e3 100644 --- a/rb/lib/selenium/webdriver/chromium/profile.rb +++ b/rb/lib/selenium/webdriver/chromium/profile.rb @@ -27,6 +27,7 @@ module Chromium class Profile include ProfileHelper + # @rbs (?nil) -> void def initialize(model = nil) @model = verify_model(model) @extensions = [] @@ -34,6 +35,7 @@ def initialize(model = nil) @directory = nil end + # @rbs (String) -> Array[untyped]? def add_extension(path) raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path) @@ -44,6 +46,7 @@ def add_encoded_extension(encoded) @encoded_extensions << encoded end + # @rbs () -> String def directory @directory || layout_on_disk end @@ -73,6 +76,7 @@ def layout_on_disk @directory end + # @rbs (*untyped) -> Hash[untyped, untyped] def as_json(*) extensions = @extensions.map do |crx_path| File.open(crx_path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read } diff --git a/rb/lib/selenium/webdriver/common/action_builder.rb b/rb/lib/selenium/webdriver/common/action_builder.rb index 16089b115d547..486c5d191bf28 100644 --- a/rb/lib/selenium/webdriver/common/action_builder.rb +++ b/rb/lib/selenium/webdriver/common/action_builder.rb @@ -38,6 +38,7 @@ class ActionBuilder # @return [ActionBuilder] A self reference. # + # @rbs (Selenium::WebDriver::Remote::BiDiBridge, ?devices: Array[untyped], ?async: bool, ?duration: Integer) -> void def initialize(bridge, devices: [], async: false, duration: 250) @bridge = bridge @duration = duration @@ -61,6 +62,7 @@ def initialize(bridge, devices: [], async: false, duration: 250) # # + # @rbs (Symbol, String) -> Selenium::WebDriver::Interactions::PointerInput def add_pointer_input(kind, name) add_input(Interactions.pointer(kind, name: name)) end @@ -77,6 +79,7 @@ def add_pointer_input(kind, name) # @return [Interactions::KeyInput] The key input added # + # @rbs (String) -> Selenium::WebDriver::Interactions::KeyInput def add_key_input(name) add_input(Interactions.key(name)) end @@ -93,6 +96,7 @@ def add_key_input(name) # @return [Interactions::WheelInput] The wheel input added # + # @rbs (String) -> Selenium::WebDriver::Interactions::WheelInput def add_wheel_input(name) add_input(Interactions.wheel(name)) end @@ -105,6 +109,7 @@ def add_wheel_input(name) # @return [Selenium::WebDriver::Interactions::InputDevice] input device with given name or type # + # @rbs (?name: nil, ?type: Symbol) -> (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput)? def device(name: nil, type: nil) input = @devices.find { |device| (device.name == name.to_s || name.nil?) && (device.type == type || type.nil?) } @@ -181,6 +186,7 @@ def pause(device: nil, duration: 0) # @return [ActionBuilder] A self reference. # + # @rbs (?device: Selenium::WebDriver::Interactions::KeyInput, ?number: Integer, ?duration: Integer) -> Selenium::WebDriver::ActionBuilder def pauses(device: nil, number: nil, duration: 0) number ||= 2 device ||= pointer_input @@ -194,6 +200,7 @@ def pauses(device: nil, number: nil, duration: 0) # Executes the actions added to the builder. # + # @rbs () -> nil def perform @bridge.send_actions @devices.filter_map(&:encode) clear_all_actions @@ -204,6 +211,7 @@ def perform # Clears all actions from the builder. # + # @rbs () -> Array[untyped] def clear_all_actions @devices.each(&:clear_actions) end @@ -212,6 +220,7 @@ def clear_all_actions # Releases all action states from the browser. # + # @rbs () -> void def release_actions @bridge.release_actions end @@ -224,6 +233,7 @@ def release_actions # @param [Array[InputDevice]] action_devices Array of Input Devices performing an action in this tick. # + # @rbs (*Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput | Selenium::WebDriver::Interactions::WheelInput) -> void def tick(*action_devices) return if @async @@ -234,6 +244,7 @@ def tick(*action_devices) # Adds an InputDevice # + # @rbs (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput | Symbol | Selenium::WebDriver::Interactions::WheelInput) -> (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput | Selenium::WebDriver::Interactions::WheelInput) def add_input(device) device = Interactions.send(device) if device.is_a?(Symbol) && Interactions.respond_to?(device) diff --git a/rb/lib/selenium/webdriver/common/alert.rb b/rb/lib/selenium/webdriver/common/alert.rb index 87575c4d1ebc9..643f148879b78 100644 --- a/rb/lib/selenium/webdriver/common/alert.rb +++ b/rb/lib/selenium/webdriver/common/alert.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver class Alert + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge @@ -27,18 +28,22 @@ def initialize(bridge) bridge.alert_text end + # @rbs () -> void def accept @bridge.accept_alert end + # @rbs () -> void def dismiss @bridge.dismiss_alert end + # @rbs (String) -> void def send_keys(keys) @bridge.alert = keys end + # @rbs () -> String? def text @bridge.alert_text end diff --git a/rb/lib/selenium/webdriver/common/child_process.rb b/rb/lib/selenium/webdriver/common/child_process.rb index 5a7f8e7770446..5d7d647e70d6d 100644 --- a/rb/lib/selenium/webdriver/common/child_process.rb +++ b/rb/lib/selenium/webdriver/common/child_process.rb @@ -64,6 +64,7 @@ def start Process.detach(@pid) if detach end + # @rbs (?Integer) -> nil def stop(timeout = 3) return unless @pid return if exited? @@ -113,6 +114,7 @@ def wait private + # @rbs (Integer) -> nil def terminate_and_wait_else_kill(timeout) WebDriver.logger.debug("Sending TERM to process: #{@pid}", id: :process) terminate(@pid) @@ -126,6 +128,7 @@ def terminate_and_wait_else_kill(timeout) WebDriver.logger.debug(" -> killed #{@pid}", id: :process) end + # @rbs (Integer) -> void def terminate(pid) Process.kill(SIGTERM, pid) end diff --git a/rb/lib/selenium/webdriver/common/driver.rb b/rb/lib/selenium/webdriver/common/driver.rb index 1d7a104cddf5f..04e74eb9f6786 100644 --- a/rb/lib/selenium/webdriver/common/driver.rb +++ b/rb/lib/selenium/webdriver/common/driver.rb @@ -77,6 +77,7 @@ def initialize(bridge: nil, listener: nil, **opts) add_extensions(@bridge.browser) end + # @rbs () -> String def inspect format '#<%s:0x%x browser=%s>', class: self.class, hash: hash * 2, browser: bridge.browser.inspect @@ -88,6 +89,7 @@ def inspect # # @return [Hash] # + # @rbs () -> Hash[untyped, untyped] def status @bridge.status end @@ -107,6 +109,7 @@ def navigate # @see Script # + # @rbs () -> Selenium::WebDriver::Script? def script @script ||= WebDriver::Script.new(bridge) end @@ -116,6 +119,7 @@ def script # @see TargetLocator # + # @rbs () -> Selenium::WebDriver::TargetLocator def switch_to @switch_to ||= WebDriver::TargetLocator.new(bridge) end @@ -125,6 +129,7 @@ def switch_to # @see Manager # + # @rbs () -> Selenium::WebDriver::Manager def manage bridge.manage end @@ -134,6 +139,7 @@ def manage # @see ActionBuilder # + # @rbs (**nil) -> Selenium::WebDriver::ActionBuilder def action(**opts) bridge.action(**opts) end @@ -142,6 +148,7 @@ def action(**opts) # Opens the specified URL in the browser. # + # @rbs (String) -> nil def get(url) navigate.to(url) end @@ -152,6 +159,7 @@ def get(url) # @return [String] # + # @rbs () -> String def current_url bridge.url end @@ -162,6 +170,7 @@ def current_url # @return [String] # + # @rbs () -> String def title bridge.title end @@ -172,6 +181,7 @@ def title # @return [String] # + # @rbs () -> String def page_source bridge.page_source end @@ -192,6 +202,7 @@ def quit # Close the current window, or the browser if no windows are left. # + # @rbs () -> Array[untyped] def close bridge&.close end @@ -203,6 +214,7 @@ def close # @see TargetLocator#window # + # @rbs () -> Array[untyped] def window_handles bridge.window_handles end @@ -213,6 +225,7 @@ def window_handles # @return [String] # + # @rbs () -> String def window_handle bridge.window_handle end @@ -249,6 +262,7 @@ def execute_script(script, *args) # @return [WebDriver::Element,Integer,Float,Boolean,NilClass,String,Array] # + # @rbs (String, *Array[untyped] | nil) -> Hash[untyped, untyped] def execute_async_script(script, *args) bridge.execute_async_script(script, *args) end @@ -258,6 +272,7 @@ def execute_async_script(script, *args) # @see VirtualAuthenticator # + # @rbs (Selenium::WebDriver::VirtualAuthenticatorOptions) -> Selenium::WebDriver::VirtualAuthenticator def add_virtual_authenticator(options) bridge.add_virtual_authenticator(options) end @@ -297,16 +312,19 @@ def network # driver[:tag_name => 'div'] #=> # # + # @rbs (Symbol | Hash[untyped, untyped]) -> Selenium::WebDriver::Element def [](sel) sel = {id: sel} if sel.is_a?(String) || sel.is_a?(Symbol) find_element sel end + # @rbs () -> Symbol def browser bridge.browser end + # @rbs () -> Selenium::WebDriver::Remote::Capabilities def capabilities bridge.capabilities end @@ -316,6 +334,7 @@ def capabilities # @see SearchContext # + # @rbs () -> Array[untyped] def ref [:driver, nil] end @@ -338,6 +357,7 @@ def service_url(service) @service_manager.uri end + # @rbs () -> String def screenshot bridge.screenshot end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb b/rb/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb index f36a84da93f67..bc7db63d78204 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb @@ -27,6 +27,7 @@ module DownloadsFiles # @param [String] path # + # @rbs (String) -> Hash[untyped, untyped] def download_path=(path) params = { 'cmd' => 'Page.setDownloadBehavior', diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb b/rb/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb index 3d9ba3fc02062..abe7fd96470ee 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb @@ -27,12 +27,14 @@ module FullPageScreenshot # @api public # + # @rbs (String) -> File def save_full_page_screenshot(path) save_screenshot(path, full_page: true) end private + # @rbs () -> String def full_screenshot @bridge.full_screenshot end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_addons.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_addons.rb index dbe6def2672a1..2987c5f5ce1f6 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_addons.rb @@ -29,6 +29,7 @@ module HasAddons # @return [String] identifier of installed addon # + # @rbs (String, ?bool?) -> String def install_addon(path, temporary = nil) @bridge.install_addon(path, temporary) end @@ -39,6 +40,7 @@ def install_addon(path, temporary = nil) # @param [String] id Identifier of installed addon # + # @rbs (String) -> void def uninstall_addon(id) @bridge.uninstall_addon(id) end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb index 0e9c67f51e5c2..431c7651c8f60 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb @@ -39,6 +39,7 @@ module HasAuthentication # @param [Regexp] uri to associate the credentials with # + # @rbs (username: String, password: String, ?uri: Regexp) -> void def register(username:, password:, uri: //) auth_handlers << {username: username, password: password, uri: uri} @@ -54,10 +55,12 @@ def register(username:, password:, uri: //) private + # @rbs () -> Array[untyped] def auth_handlers @auth_handlers ||= [] end + # @rbs (String, String) -> Hash[untyped, untyped] def authenticate(request_id, url) credentials = auth_handlers.find do |handler| url.match?(handler[:uri]) diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb index 859e44737e705..64426ee7d09ad 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb @@ -27,6 +27,7 @@ module HasBiDi # @return [BiDi] # + # @rbs () -> Selenium::WebDriver::BiDi def bidi @bridge.bidi end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_casting.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_casting.rb index 551b3efa4b0ff..b299a84fe4f72 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_casting.rb @@ -27,6 +27,7 @@ module HasCasting # @return [Array] list of sinks available for casting with id and name values # + # @rbs () -> Array[untyped] def cast_sinks @bridge.cast_sinks end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_context.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_context.rb index 283858e031f6a..f2214967405e0 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_context.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_context.rb @@ -29,10 +29,12 @@ module HasContext # @param [String] value which context gets set (either 'chrome' or 'content') # + # @rbs (String) -> void def context=(value) @bridge.context = value end + # @rbs () -> String def context @bridge.context end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb index 74fc6e80f6759..7dea346f3048a 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb @@ -27,6 +27,7 @@ module HasDevTools # @return [DevTools] # + # @rbs (?target_type: String) -> Selenium::WebDriver::DevTools? def devtools(target_type: 'page') @devtools ||= {} @devtools[target_type] ||= begin diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb index c22eaf9a37898..b6969a466c553 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb @@ -25,6 +25,7 @@ module HasFedCmDialog # # FedCm by default delays promise resolution in failure cases for privacy reasons. # This method allows turning it off to let tests run faster where this is not relevant. + # @rbs (bool) -> nil def enable_fedcm_delay=(enable) @bridge.fedcm_delay(enable) end @@ -33,14 +34,17 @@ def enable_fedcm_delay=(enable) # # If a user agent triggers a cooldown when the account chooser is dismissed, # this method resets that cooldown so that the dialog can be triggered again immediately. + # @rbs () -> nil def reset_fedcm_cooldown @bridge.reset_fedcm_cooldown end + # @rbs () -> Selenium::WebDriver::FedCM::Dialog def fedcm_dialog @fedcm_dialog ||= FedCM::Dialog.new(@bridge) end + # @rbs (?timeout: Integer, ?interval: Float, ?message: nil, ?ignore: nil) -> Selenium::WebDriver::FedCM::Dialog def wait_for_fedcm_dialog(timeout: 5, interval: 0.2, message: nil, ignore: nil) wait = Wait.new(timeout: timeout, interval: interval, message: message, ignore: ignore) wait.until do diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb index 0613862db6578..be91adc879742 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb @@ -21,12 +21,14 @@ module Selenium module WebDriver module DriverExtensions module HasFileDownloads + # @rbs () -> Array[untyped]? def downloadable_files verify_enabled @bridge.downloadable_files['names'] end + # @rbs (String, String) -> void def download_file(file_name, target_directory) verify_enabled @@ -46,6 +48,7 @@ def download_file(file_name, target_directory) end end + # @rbs () -> void def delete_downloadable_files verify_enabled @@ -54,6 +57,7 @@ def delete_downloadable_files private + # @rbs () -> void def verify_enabled return if capabilities['se:downloadsEnabled'] diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb index 8acadbe0b8519..98f67b8c34ce9 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb @@ -56,6 +56,7 @@ module HasLogEvents # @yieldparam [DevTools::ConsoleEvent, DevTools::ExceptionEvent, DevTools::MutationEvent] # + # @rbs (Symbol) -> void def on_log_event(kind, &block) if browser == :firefox WebDriver.logger.deprecate( @@ -76,10 +77,12 @@ def on_log_event(kind, &block) private + # @rbs () -> Hash[untyped, untyped] def log_listeners @log_listeners ||= Hash.new { |listeners, kind| listeners[kind] = [] } end + # @rbs () -> Array[untyped] def log_console_events devtools.runtime.on(:console_api_called) do |params| event = DevTools::ConsoleEvent.new( @@ -94,6 +97,7 @@ def log_console_events end end + # @rbs () -> Array[untyped] def log_exception_events devtools.runtime.on(:exception_thrown) do |params| description = if params.dig('exceptionDetails', 'exception') @@ -114,6 +118,7 @@ def log_exception_events end end + # @rbs () -> Array[untyped] def log_mutation_events devtools.page.enable @@ -124,6 +129,7 @@ def log_mutation_events devtools.runtime.on(:binding_called) { |event| log_mutation_event(event) } end + # @rbs (Hash[untyped, untyped]) -> Array[untyped] def log_mutation_event(params) payload = JSON.parse(params['payload']) elements = find_elements(css: "*[data-__webdriver_id='#{payload['target']}']") @@ -141,6 +147,7 @@ def log_mutation_event(params) end end + # @rbs () -> String def mutation_listener @mutation_listener ||= read_atom(:mutationListener) end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_logs.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_logs.rb index 4338587edfb3c..a88b4fe64d5ca 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_logs.rb @@ -21,6 +21,7 @@ module Selenium module WebDriver module DriverExtensions module HasLogs + # @rbs () -> Selenium::WebDriver::Logs def logs @logs ||= Logs.new(@bridge) end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb index 63482d43c8f2e..959ce323bea2f 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb @@ -27,6 +27,7 @@ module HasNetworkConditions # @return [Hash] # + # @rbs () -> Hash[untyped, untyped]? def network_conditions @bridge.network_conditions end @@ -42,6 +43,7 @@ def network_conditions # @option conditions [Boolean] :offline # + # @rbs (Hash[untyped, untyped]) -> void def network_conditions=(conditions) conditions[:latency] ||= 0 unless conditions.key?(:throughput) @@ -57,6 +59,7 @@ def network_conditions=(conditions) # Resets Chromium network emulation settings. # + # @rbs () -> void def delete_network_conditions @bridge.delete_network_conditions end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb index e93ae0b3e6e76..c4acb853e4593 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb @@ -59,6 +59,7 @@ module HasNetworkInterception # @yieldparam [Proc] continue block which proceeds with the request and optionally yields response # + # @rbs () -> void def intercept(&block) if browser == :firefox WebDriver.logger.deprecate( diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb index 429731f1af018..8345cfd2e6139 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb @@ -28,6 +28,7 @@ module HasPermissions # @param [String] value what to set the permission to # + # @rbs (String, String) -> void def add_permission(name, value) @bridge.set_permission(name, value) end @@ -38,6 +39,7 @@ def add_permission(name, value) # @param [Hash] opt key/value pairs to set permissions # + # @rbs (Hash[untyped, untyped]) -> void def add_permissions(opt) opt.each do |key, value| @bridge.set_permission(key, value) diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb index 190ad87babf84..d68aac5bacb6d 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb @@ -27,6 +27,7 @@ module HasPinnedScripts # @return [Array] # + # @rbs () -> Array[untyped] def pinned_scripts @pinned_scripts ||= [] end @@ -46,6 +47,7 @@ def pinned_scripts # @return [DevTools::PinnedScript] # + # @rbs (String) -> Selenium::WebDriver::DevTools::PinnedScript def pin_script(script) script = DevTools::PinnedScript.new(script) pinned_scripts << script @@ -64,6 +66,7 @@ def pin_script(script) # @param [DevTools::PinnedScript] script # + # @rbs (Selenium::WebDriver::DevTools::PinnedScript) -> void def unpin_script(script) devtools.runtime.evaluate(expression: script.remove) devtools.page.remove_script_to_evaluate_on_new_document(identifier: script.devtools_identifier) diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb index 364870bec0503..88459e325d5da 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb @@ -30,6 +30,7 @@ module HasSessionId # @api public # + # @rbs () -> String def session_id @bridge.session_id end diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/prints_page.rb b/rb/lib/selenium/webdriver/common/driver_extensions/prints_page.rb index 8025bbda229b3..6d0a22f24d6bc 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/prints_page.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/prints_page.rb @@ -32,6 +32,7 @@ module PrintsPage # @api public # + # @rbs (String, **nil) -> void def save_print_page(path, **options) File.open(path, 'wb') do |file| content = Base64.decode64 print_page(**options) @@ -47,6 +48,7 @@ def save_print_page(path, **options) # @api public # + # @rbs (**nil | String | String | Array[untyped] | Hash[untyped, untyped]) -> String def print_page(**options) options[:pageRanges] = Array(options.delete(:page_ranges)) || [] options[:shrinkToFit] = options.delete(:shrink_to_fit) { true } diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb b/rb/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb index c02b411c11b7f..29e03607a130b 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb @@ -49,6 +49,7 @@ module UploadsFiles # @api public # + # @rbs (Proc?) -> Proc? def file_detector=(detector) raise ArgumentError, 'detector must respond to #call' unless detector.nil? || detector.respond_to?(:call) diff --git a/rb/lib/selenium/webdriver/common/element.rb b/rb/lib/selenium/webdriver/common/element.rb index 48b506ecc7a62..32fe27ff3eda7 100644 --- a/rb/lib/selenium/webdriver/common/element.rb +++ b/rb/lib/selenium/webdriver/common/element.rb @@ -31,6 +31,7 @@ class Element # @api private # + # @rbs (Selenium::WebDriver::Remote::Bridge, String) -> void def initialize(bridge, id) @bridge = bridge @id = id @@ -40,11 +41,13 @@ def inspect format '#<%s:0x%x id=%s>', class: self.class, hash: hash * 2, id: @id.inspect end + # @rbs (Selenium::WebDriver::Element) -> bool def ==(other) other.is_a?(self.class) && ref == other.ref end alias eql? == + # @rbs () -> Integer def hash [@id, @bridge].hash end @@ -73,6 +76,7 @@ def hash # defined # + # @rbs () -> nil def click bridge.click_element @id end @@ -87,6 +91,7 @@ def click # @return [String] The tag name of this element. # + # @rbs () -> String def tag_name bridge.element_tag_name @id end @@ -123,6 +128,7 @@ def tag_name # @see #property # + # @rbs (String) -> String def attribute(name) bridge.element_attribute self, name end @@ -142,6 +148,7 @@ def attribute(name) # @see #property # + # @rbs (String) -> String? def dom_attribute(name) bridge.element_dom_attribute @id, name end @@ -156,6 +163,7 @@ def dom_attribute(name) # @return [String, nil] property value # + # @rbs (Symbol) -> String def property(name) bridge.element_property @id, name end @@ -166,6 +174,7 @@ def property(name) # @return [String] # + # @rbs () -> String def aria_role bridge.element_aria_role @id end @@ -176,6 +185,7 @@ def aria_role # @return [String] # + # @rbs () -> String def accessible_name bridge.element_aria_label @id end @@ -186,6 +196,7 @@ def accessible_name # @return [String] # + # @rbs () -> String def text bridge.element_text @id end @@ -204,6 +215,7 @@ def text # @see Keys::KEYS # + # @rbs (*String) -> void def send_keys(*args) bridge.send_keys_to_element @id, Keys.encode(args) end @@ -219,6 +231,7 @@ def send_keys(*args) # consider following with a call to #send_keys with the tab key. # + # @rbs () -> nil def clear bridge.clear_element @id end @@ -229,6 +242,7 @@ def clear # @return [Boolean] # + # @rbs () -> bool def enabled? bridge.element_enabled? @id end @@ -239,6 +253,7 @@ def enabled? # @return [Boolean] # + # @rbs () -> bool def selected? bridge.element_selected? @id end @@ -249,6 +264,7 @@ def selected? # @return [Boolean] # + # @rbs () -> bool def displayed? bridge.element_displayed? self end @@ -257,6 +273,7 @@ def displayed? # Submit this element # + # @rbs () -> nil def submit bridge.submit_element @id end @@ -272,6 +289,7 @@ def submit # @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration # + # @rbs (String) -> String def css_value(prop) bridge.element_value_of_css_property @id, prop end @@ -283,6 +301,7 @@ def css_value(prop) # @return [WebDriver::Point] # + # @rbs () -> Selenium::WebDriver::Point def location bridge.element_location @id end @@ -293,6 +312,7 @@ def location # @return [WebDriver::Rectangle] # + # @rbs () -> Selenium::WebDriver::Rectangle def rect bridge.element_rect @id end @@ -303,6 +323,7 @@ def rect # @return [WebDriver::Point] # + # @rbs () -> Selenium::WebDriver::Point def location_once_scrolled_into_view bridge.element_location_once_scrolled_into_view @id end @@ -313,6 +334,7 @@ def location_once_scrolled_into_view # @return [WebDriver::Dimension] # + # @rbs () -> Selenium::WebDriver::Dimension def size bridge.element_size @id end @@ -323,6 +345,7 @@ def size # @return [WebDriver::ShadowRoot] # + # @rbs () -> Selenium::WebDriver::ShadowRoot? def shadow_root bridge.shadow_root @id end @@ -351,6 +374,7 @@ def shadow_root # @see SearchContext # + # @rbs () -> Array[untyped] def ref [:element, @id] end @@ -362,6 +386,7 @@ def ref # @api private # + # @rbs (*untyped) -> String def to_json(*) JSON.generate as_json end @@ -372,6 +397,7 @@ def to_json(*) # @api private # + # @rbs (*untyped) -> Hash[untyped, untyped] def as_json(*) @id.is_a?(Hash) ? @id : {ELEMENT_KEY => @id} end @@ -387,6 +413,7 @@ def selectable? tn == 'option' || (tn == 'input' && %w[radio checkbox].include?(type)) end + # @rbs () -> String def screenshot bridge.element_screenshot(@id) end diff --git a/rb/lib/selenium/webdriver/common/error.rb b/rb/lib/selenium/webdriver/common/error.rb index d50a4c83b6798..66b4602437c02 100644 --- a/rb/lib/selenium/webdriver/common/error.rb +++ b/rb/lib/selenium/webdriver/common/error.rb @@ -46,12 +46,14 @@ def self.for_error(error) }.freeze class WebDriverError < StandardError + # @rbs (?String) -> void def initialize(msg = '') # Remove this conditional when all the error pages have been documented super(URLS[class_name] ? "#{msg}; #{SUPPORT_MSG} #{URLS[class_name]}" : msg) end # steep:ignore:start + # @rbs () -> Symbol def class_name self.class.name.split('::')&.last&.to_sym end diff --git a/rb/lib/selenium/webdriver/common/fedcm/account.rb b/rb/lib/selenium/webdriver/common/fedcm/account.rb index 29f5974e198b6..b278aff177006 100644 --- a/rb/lib/selenium/webdriver/common/fedcm/account.rb +++ b/rb/lib/selenium/webdriver/common/fedcm/account.rb @@ -31,6 +31,7 @@ class Account :idp_config_url, :login_state, :terms_of_service_url, :privacy_policy_url # steep:ignore:start + # @rbs (**String) -> void def initialize(**args) @account_id = args['accountId'] @email = args['email'] diff --git a/rb/lib/selenium/webdriver/common/fedcm/dialog.rb b/rb/lib/selenium/webdriver/common/fedcm/dialog.rb index 8ef245cd31c57..37f0cf98ca80c 100644 --- a/rb/lib/selenium/webdriver/common/fedcm/dialog.rb +++ b/rb/lib/selenium/webdriver/common/fedcm/dialog.rb @@ -21,6 +21,7 @@ module Selenium module WebDriver module FedCM class Dialog + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end @@ -29,11 +30,13 @@ def initialize(bridge) DIALOG_TYPE_AUTO_REAUTH = 'AutoReauthn' # Closes the dialog as if the user had clicked X. + # @rbs () -> nil def click @bridge.click_fedcm_dialog_button end # Closes the dialog as if the user had clicked X. + # @rbs () -> nil def cancel @bridge.cancel_fedcm_dialog end @@ -41,6 +44,7 @@ def cancel # Selects an account as if the user had clicked on it. # # @param [Integer] index The index of the account to select from the list returned by get_accounts. + # @rbs (Integer) -> nil def select_account(index) @bridge.select_fedcm_account index end @@ -48,16 +52,19 @@ def select_account(index) # Returns the type of the open dialog. # # One of DIALOG_TYPE_ACCOUNT_LIST and DIALOG_TYPE_AUTO_REAUTH. + # @rbs () -> String? def type @bridge.fedcm_dialog_type end # Returns the title of the dialog. + # @rbs () -> String? def title @bridge.fedcm_title end # Returns the subtitle of the dialog or nil if none. + # @rbs () -> nil def subtitle @bridge.fedcm_subtitle end @@ -65,6 +72,7 @@ def subtitle # Returns the accounts shown in the account chooser. # # If this is an auto reauth dialog, returns the single account that is being signed in. + # @rbs () -> Array[untyped]? def accounts @bridge.fedcm_account_list.map { |account| Account.new(**account) } end diff --git a/rb/lib/selenium/webdriver/common/file_reaper.rb b/rb/lib/selenium/webdriver/common/file_reaper.rb index 4c64d2ba0a974..c9a8435e5d412 100644 --- a/rb/lib/selenium/webdriver/common/file_reaper.rb +++ b/rb/lib/selenium/webdriver/common/file_reaper.rb @@ -31,11 +31,13 @@ def reap? @reap = defined?(@reap) ? @reap : true end + # @rbs () -> Array[untyped] def tmp_files @tmp_files ||= Hash.new { |hash, pid| hash[pid] = [] } @tmp_files[Process.pid] end + # @rbs (String) -> void def <<(file) tmp_files << file end diff --git a/rb/lib/selenium/webdriver/common/interactions/input_device.rb b/rb/lib/selenium/webdriver/common/interactions/input_device.rb index b0d1ddedf81e4..53b5f5649965c 100644 --- a/rb/lib/selenium/webdriver/common/interactions/input_device.rb +++ b/rb/lib/selenium/webdriver/common/interactions/input_device.rb @@ -32,25 +32,30 @@ module Interactions class InputDevice attr_reader :name, :actions, :type + # @rbs (?String?) -> void def initialize(name = nil) @name = name || SecureRandom.uuid @actions = [] end + # @rbs (Selenium::WebDriver::Interactions::KeyInput::TypingInteraction | Selenium::WebDriver::Interactions::PointerMove | Selenium::WebDriver::Interactions::PointerPress | Selenium::WebDriver::Interactions::Pause | Selenium::WebDriver::Interactions::Scroll) -> Array[untyped] def add_action(action) raise TypeError, "#{action.inspect} is not a valid action" unless action.class < Interaction @actions << action end + # @rbs () -> Array[untyped] def clear_actions @actions.clear end + # @rbs (?Integer) -> Array[untyped] def create_pause(duration = 0) add_action(Pause.new(self, duration)) end + # @rbs () -> Hash[untyped, untyped] def encode {type: type, id: name, actions: @actions.map(&:encode)} unless @actions.empty? end diff --git a/rb/lib/selenium/webdriver/common/interactions/interaction.rb b/rb/lib/selenium/webdriver/common/interactions/interaction.rb index 8bea94ccec462..ea41a909c8770 100644 --- a/rb/lib/selenium/webdriver/common/interactions/interaction.rb +++ b/rb/lib/selenium/webdriver/common/interactions/interaction.rb @@ -30,6 +30,7 @@ module Interactions class Interaction attr_reader :type + # @rbs (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput | Selenium::WebDriver::Interactions::WheelInput) -> void def initialize(source) assert_source(source) end diff --git a/rb/lib/selenium/webdriver/common/interactions/interactions.rb b/rb/lib/selenium/webdriver/common/interactions/interactions.rb index fe7179abb94f9..f59a77ad176b1 100644 --- a/rb/lib/selenium/webdriver/common/interactions/interactions.rb +++ b/rb/lib/selenium/webdriver/common/interactions/interactions.rb @@ -30,10 +30,12 @@ module Interactions # class << self + # @rbs (?String) -> Selenium::WebDriver::Interactions::KeyInput def key(name = nil) KeyInput.new(name) end + # @rbs (?Symbol, ?name: String | nil) -> Selenium::WebDriver::Interactions::PointerInput def pointer(kind = :mouse, name: nil) PointerInput.new(kind, name: name) end @@ -42,6 +44,7 @@ def mouse(name: nil) pointer(name: name) end + # @rbs (?name: nil) -> Selenium::WebDriver::Interactions::PointerInput def pen(name: nil) pointer(:pen, name: name) end @@ -54,6 +57,7 @@ def none(name = nil) NoneInput.new(name) end + # @rbs (?String) -> Selenium::WebDriver::Interactions::WheelInput def wheel(name = nil) WheelInput.new(name) end diff --git a/rb/lib/selenium/webdriver/common/interactions/key_actions.rb b/rb/lib/selenium/webdriver/common/interactions/key_actions.rb index 9f73e9d2d8e37..cc536ec3abb48 100644 --- a/rb/lib/selenium/webdriver/common/interactions/key_actions.rb +++ b/rb/lib/selenium/webdriver/common/interactions/key_actions.rb @@ -44,6 +44,7 @@ module KeyActions # @return [ActionBuilder] A self reference # + # @rbs (*String | Symbol, ?device: nil) -> Selenium::WebDriver::ActionBuilder def key_down(*args, device: nil) key_action(*args, action: :create_key_down, device: device) end @@ -71,6 +72,7 @@ def key_down(*args, device: nil) # @return [ActionBuilder] A self reference # + # @rbs (*String | Symbol, ?device: nil) -> Selenium::WebDriver::ActionBuilder def key_up(*args, device: nil) key_action(*args, action: :create_key_up, device: device) end @@ -101,6 +103,7 @@ def key_up(*args, device: nil) # @return [ActionBuilder] A self reference # + # @rbs (*String | Selenium::WebDriver::Element | String | String | Symbol, ?device: nil) -> Selenium::WebDriver::ActionBuilder def send_keys(*args, device: nil) click(args.shift) if args.first.is_a? Element args.map { |x| x.is_a?(String) ? x.chars : x }.flatten.each do |arg| @@ -133,6 +136,7 @@ def send_keys(*args, device: nil) # @return [ActionBuilder] A self reference # + # @rbs (*String | Symbol, ?action: Symbol, ?device: nil) -> Selenium::WebDriver::ActionBuilder def key_action(*args, action: nil, device: nil) key_input = key_input(device) click(args.shift) if args.first.is_a? Element @@ -141,6 +145,7 @@ def key_action(*args, action: nil, device: nil) self end + # @rbs (?nil) -> Selenium::WebDriver::Interactions::KeyInput def key_input(name = nil) device(name: name, type: Interactions::KEY) || add_key_input('keyboard') end diff --git a/rb/lib/selenium/webdriver/common/interactions/key_input.rb b/rb/lib/selenium/webdriver/common/interactions/key_input.rb index 5c8ee371eb2cb..60c56ef52d3e1 100644 --- a/rb/lib/selenium/webdriver/common/interactions/key_input.rb +++ b/rb/lib/selenium/webdriver/common/interactions/key_input.rb @@ -29,15 +29,18 @@ module Interactions class KeyInput < InputDevice SUBTYPES = {down: :keyDown, up: :keyUp, pause: :pause}.freeze + # @rbs (?String) -> void def initialize(name = nil) super @type = Interactions::KEY end + # @rbs (String | Symbol) -> Array[untyped] def create_key_down(key) add_action(TypingInteraction.new(self, :down, key)) end + # @rbs (String | Symbol) -> Array[untyped] def create_key_up(key) add_action(TypingInteraction.new(self, :up, key)) end diff --git a/rb/lib/selenium/webdriver/common/interactions/pause.rb b/rb/lib/selenium/webdriver/common/interactions/pause.rb index 2c5ad4c775bd8..48210664e6452 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pause.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pause.rb @@ -28,16 +28,19 @@ module Interactions # class Pause < Interaction + # @rbs (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput, ?Integer) -> void def initialize(source, duration = nil) super(source) @duration = duration @type = :pause end + # @rbs (Selenium::WebDriver::Interactions::KeyInput | Selenium::WebDriver::Interactions::PointerInput) -> nil def assert_source(source) raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? InputDevice end + # @rbs () -> Hash[untyped, untyped] def encode output = {type: type} output[:duration] = (@duration * 1000).to_i if @duration diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb index baa1034c86349..dcc5bb14fdae4 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb @@ -27,6 +27,7 @@ module PointerActions # It can be overridden with default_move_duration= # + # @rbs () -> Float def default_move_duration @default_move_duration ||= @duration / 1000.0 # convert ms to seconds end @@ -46,6 +47,7 @@ def default_move_duration # @return [ActionBuilder] A self reference. # + # @rbs (?Symbol, ?device: nil, **nil) -> Selenium::WebDriver::ActionBuilder def pointer_down(button = :left, device: nil, **opts) button_action(button, :create_pointer_down, device: device, **opts) end @@ -63,6 +65,7 @@ def pointer_down(button = :left, device: nil, **opts) # @return [ActionBuilder] A self reference. # + # @rbs (?Symbol, ?device: nil, **nil) -> Selenium::WebDriver::ActionBuilder def pointer_up(button = :left, device: nil, **opts) button_action(button, :create_pointer_up, device: device, **opts) end @@ -94,6 +97,7 @@ def pointer_up(button = :left, device: nil, **opts) # @return [ActionBuilder] A self reference. # + # @rbs (Selenium::WebDriver::Element, ?Integer?, ?Integer?, **nil) -> Selenium::WebDriver::ActionBuilder def move_to(element, right_by = nil, down_by = nil, **opts) pointer = pointer_input(opts.delete(:device)) pointer.create_pointer_move(duration: opts.delete(:duration) || default_move_duration, @@ -122,6 +126,7 @@ def move_to(element, right_by = nil, down_by = nil, **opts) # @raise [MoveTargetOutOfBoundsError] if the provided offset is outside the document's boundaries. # + # @rbs (Integer, Integer | Float, ?device: nil, ?duration: Float, **nil | Float | Integer) -> Selenium::WebDriver::ActionBuilder def move_by(right_by, down_by, device: nil, duration: default_move_duration, **opts) pointer = pointer_input(device) pointer.create_pointer_move(duration: duration, @@ -150,6 +155,7 @@ def move_by(right_by, down_by, device: nil, duration: default_move_duration, **o # @raise [MoveTargetOutOfBoundsError] if the provided x or y value is outside the document's boundaries. # + # @rbs (Integer, Integer, ?device: nil, ?duration: Float, **nil) -> Selenium::WebDriver::ActionBuilder def move_to_location(x, y, device: nil, duration: default_move_duration, **opts) pointer = pointer_input(device) pointer.create_pointer_move(duration: duration, @@ -177,6 +183,7 @@ def move_to_location(x, y, device: nil, duration: default_move_duration, **opts) # @return [ActionBuilder] A self reference. # + # @rbs (?Selenium::WebDriver::Element, ?button: nil, ?device: nil) -> Selenium::WebDriver::ActionBuilder def click_and_hold(element = nil, button: nil, device: nil) move_to(element, device: device) if element pointer_down(button || :left, device: device) @@ -196,6 +203,7 @@ def click_and_hold(element = nil, button: nil, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (?button: nil, ?device: nil) -> void def release(button: nil, device: nil) pointer_up(button || :left, device: device) self @@ -223,6 +231,7 @@ def release(button: nil, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (?Selenium::WebDriver::Element?, ?button: nil | Symbol, ?device: nil) -> Selenium::WebDriver::ActionBuilder def click(element = nil, button: nil, device: nil) move_to(element, device: device) if element pointer_down(button || :left, device: device) @@ -252,6 +261,7 @@ def click(element = nil, button: nil, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (?Selenium::WebDriver::Element, ?device: nil) -> Selenium::WebDriver::ActionBuilder def double_click(element = nil, device: nil) move_to(element, device: device) if element click(device: device) @@ -280,6 +290,7 @@ def double_click(element = nil, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (?Selenium::WebDriver::Element, ?device: nil) -> Selenium::WebDriver::ActionBuilder def context_click(element = nil, device: nil) click(element, button: :right, device: device) end @@ -303,6 +314,7 @@ def context_click(element = nil, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (Selenium::WebDriver::Element, Selenium::WebDriver::Element, ?device: nil) -> Selenium::WebDriver::ActionBuilder def drag_and_drop(source, target, device: nil) click_and_hold(source, device: device) move_to(target, device: device) @@ -327,6 +339,7 @@ def drag_and_drop(source, target, device: nil) # @return [ActionBuilder] A self reference. # + # @rbs (Selenium::WebDriver::Element, Integer, Integer, ?device: nil) -> Selenium::WebDriver::ActionBuilder def drag_and_drop_by(source, right_by, down_by, device: nil) click_and_hold(source, device: device) move_by(right_by, down_by, device: device) @@ -336,6 +349,7 @@ def drag_and_drop_by(source, right_by, down_by, device: nil) private + # @rbs (Symbol, Symbol, ?device: nil, **nil) -> Selenium::WebDriver::ActionBuilder def button_action(button, action, device: nil, **opts) pointer = pointer_input(device) pointer.send(action, button, **opts) @@ -343,6 +357,7 @@ def button_action(button, action, device: nil, **opts) self end + # @rbs (?nil) -> Selenium::WebDriver::Interactions::PointerInput def pointer_input(name = nil) device(name: name, type: Interactions::POINTER) || add_pointer_input(:mouse, 'mouse') end diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb index c63327091e81e..e0e4b7b7a1f20 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb @@ -31,6 +31,7 @@ module PointerEventProperties altitude_angle: {'altitudeAngle' => {min: 0.0, max: (Math::PI / 2)}}, azimuth_angle: {'azimuthAngle' => {min: 0.0, max: (Math::PI * 2)}}}.freeze + # @rbs () -> Hash[untyped, untyped] def process_opts raise ArgumentError, "Unknown options found: #{@opts.inspect}" unless (@opts.keys - VALID.keys).empty? @@ -45,6 +46,7 @@ def process_opts private + # @rbs (Float | Integer, Float | Integer, ?Float | Integer) -> (Float | Integer) def assert_number(num, min, max = nil) return if num.nil? diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_input.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_input.rb index ec9a323d4c748..ef87a90660e88 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_input.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_input.rb @@ -31,32 +31,38 @@ class PointerInput < InputDevice attr_reader :kind + # @rbs (Symbol, ?name: String | nil) -> void def initialize(kind, name: nil) super(name) @kind = assert_kind(kind) @type = Interactions::POINTER end + # @rbs () -> Hash[untyped, untyped] def encode output = super output[:parameters] = {pointerType: kind} if output output end + # @rbs (Symbol) -> Symbol def assert_kind(pointer) raise TypeError, "#{pointer.inspect} is not a valid pointer type" unless KIND.key? pointer KIND[pointer] end + # @rbs (?duration: Float, ?x: Integer, ?y: Integer, ?origin: Selenium::WebDriver::Element | Symbol, **nil | Float | Integer) -> void def create_pointer_move(duration: 0, x: 0, y: 0, origin: nil, **opts) add_action(PointerMove.new(self, duration, x, y, origin: origin, **opts)) end + # @rbs (Symbol, **nil) -> Array[untyped] def create_pointer_down(button, **opts) add_action(PointerPress.new(self, :down, button, **opts)) end + # @rbs (Symbol, **nil) -> Array[untyped] def create_pointer_up(button, **opts) add_action(PointerPress.new(self, :up, button, **opts)) end diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_move.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_move.rb index abf4a6d4cb306..3f3dfe26d3e4e 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_move.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_move.rb @@ -33,6 +33,7 @@ class PointerMove < Interaction POINTER = :pointer ORIGINS = [VIEWPORT, POINTER].freeze + # @rbs (Selenium::WebDriver::Interactions::PointerInput, Float, Integer, Integer, **Selenium::WebDriver::Element | Symbol | Symbol | Float | Integer) -> void def initialize(source, duration, x, y, **opts) super(source) @duration = duration * 1000 @@ -43,10 +44,12 @@ def initialize(source, duration, x, y, **opts) @opts = opts end + # @rbs (Selenium::WebDriver::Interactions::PointerInput) -> nil def assert_source(source) raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? PointerInput end + # @rbs () -> Hash[untyped, untyped] def encode process_opts.merge('type' => type.to_s, 'duration' => @duration.to_i, diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb index e37e81f07f538..c4a92621b1658 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb @@ -41,6 +41,7 @@ class PointerPress < Interaction forward: 4}.freeze DIRECTIONS = {down: :pointerDown, up: :pointerUp}.freeze + # @rbs (Selenium::WebDriver::Interactions::PointerInput, Symbol, Symbol, **nil) -> void def initialize(source, direction, button, **opts) super(source) @direction = assert_direction(direction) @@ -49,16 +50,19 @@ def initialize(source, direction, button, **opts) @opts = opts end + # @rbs () -> Hash[untyped, untyped] def encode process_opts.merge('type' => type.to_s, 'button' => @button) end private + # @rbs (Selenium::WebDriver::Interactions::PointerInput) -> nil def assert_source(source) raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? PointerInput end + # @rbs (Symbol) -> Integer def assert_button(button) case button when Symbol @@ -74,6 +78,7 @@ def assert_button(button) end end + # @rbs (Symbol) -> Symbol def assert_direction(direction) raise ArgumentError, "#{direction.inspect} is not a valid button direction" unless DIRECTIONS.key? direction diff --git a/rb/lib/selenium/webdriver/common/interactions/scroll.rb b/rb/lib/selenium/webdriver/common/interactions/scroll.rb index 7c17e39a2bec3..f0437873dac9b 100644 --- a/rb/lib/selenium/webdriver/common/interactions/scroll.rb +++ b/rb/lib/selenium/webdriver/common/interactions/scroll.rb @@ -27,6 +27,7 @@ module Interactions # class Scroll < Interaction + # @rbs (source: Selenium::WebDriver::Interactions::WheelInput, ?origin: Selenium::WebDriver::Element | Symbol, ?duration: Float, **nil | Integer) -> void def initialize(source:, origin: :viewport, duration: 0.25, **opts) super(source) @type = :scroll @@ -40,10 +41,12 @@ def initialize(source:, origin: :viewport, duration: 0.25, **opts) raise ArgumentError, "Invalid arguments: #{opts.keys}" unless opts.empty? end + # @rbs (Selenium::WebDriver::Interactions::WheelInput) -> nil def assert_source(source) raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? WheelInput end + # @rbs () -> Hash[untyped, untyped] def encode {'type' => type.to_s, 'duration' => @duration.to_i, diff --git a/rb/lib/selenium/webdriver/common/interactions/scroll_origin.rb b/rb/lib/selenium/webdriver/common/interactions/scroll_origin.rb index 1216384199bd6..9e0c4b04b9832 100644 --- a/rb/lib/selenium/webdriver/common/interactions/scroll_origin.rb +++ b/rb/lib/selenium/webdriver/common/interactions/scroll_origin.rb @@ -22,10 +22,12 @@ module WebDriver module WheelActions class ScrollOrigin class << self + # @rbs (Selenium::WebDriver::Element, ?Integer, ?Integer) -> Selenium::WebDriver::WheelActions::ScrollOrigin def element(element, x_offset = 0, y_offset = 0) new(element, x_offset, y_offset) end + # @rbs (?Integer, ?Integer) -> Selenium::WebDriver::WheelActions::ScrollOrigin def viewport(x_offset = 0, y_offset = 0) new(:viewport, x_offset, y_offset) end @@ -37,6 +39,7 @@ def viewport(x_offset = 0, y_offset = 0) # Use a static method to access # @api private # + # @rbs (Selenium::WebDriver::Element | Symbol, Integer, Integer) -> void def initialize(origin, x_offset, y_offset) @origin = origin @x_offset = x_offset diff --git a/rb/lib/selenium/webdriver/common/interactions/typing_interaction.rb b/rb/lib/selenium/webdriver/common/interactions/typing_interaction.rb index 7effac384f4d2..723c65355b851 100644 --- a/rb/lib/selenium/webdriver/common/interactions/typing_interaction.rb +++ b/rb/lib/selenium/webdriver/common/interactions/typing_interaction.rb @@ -29,22 +29,26 @@ module Interactions class TypingInteraction < Interaction attr_reader :type + # @rbs (Selenium::WebDriver::Interactions::KeyInput, Symbol, String | Symbol) -> void def initialize(source, type, key) super(source) @type = assert_type(type) @key = Keys.encode_key(key) end + # @rbs (Selenium::WebDriver::Interactions::KeyInput) -> nil def assert_source(source) raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? KeyInput end + # @rbs (Symbol) -> Symbol def assert_type(type) raise TypeError, "#{type.inspect} is not a valid key subtype" unless KeyInput::SUBTYPES.key? type KeyInput::SUBTYPES[type] end + # @rbs () -> Hash[untyped, untyped] def encode {type: @type, value: @key} end diff --git a/rb/lib/selenium/webdriver/common/interactions/wheel_actions.rb b/rb/lib/selenium/webdriver/common/interactions/wheel_actions.rb index 2209030ce844f..af20a358cfa06 100644 --- a/rb/lib/selenium/webdriver/common/interactions/wheel_actions.rb +++ b/rb/lib/selenium/webdriver/common/interactions/wheel_actions.rb @@ -27,6 +27,7 @@ module WheelActions # It can be overridden with default_scroll_duration= # + # @rbs () -> Float def default_scroll_duration @default_scroll_duration ||= @duration / 1000.0 # convert ms to seconds end @@ -41,6 +42,7 @@ def default_scroll_duration # @param [Object] element Which element to scroll into the viewport. # @param [Object] device Which device to use to scroll # @return [Selenium::WebDriver::WheelActions] A self reference. + # @rbs (Selenium::WebDriver::Element, ?device: nil) -> Selenium::WebDriver::ActionBuilder def scroll_to(element, device: nil) scroll(origin: element, device: device) end @@ -55,6 +57,7 @@ def scroll_to(element, device: nil) # @param [Integer] delta_x Distance along X axis to scroll using the wheel. A negative value scrolls left. # @param [Integer] delta_y Distance along Y axis to scroll using the wheel. A negative value scrolls up. # @return [Selenium::WebDriver::WheelActions] A self reference. + # @rbs (Integer, Integer, ?device: nil) -> Selenium::WebDriver::ActionBuilder def scroll_by(delta_x, delta_y, device: nil) scroll(delta_x: delta_x, delta_y: delta_y, device: device) end @@ -85,6 +88,7 @@ def scroll_by(delta_x, delta_y, device: nil) # @param [Integer] delta_y Distance along Y axis to scroll using the wheel. A negative value scrolls up. # @return [Selenium::WebDriver::WheelActions] A self reference. # @raise [Error::MoveTargetOutOfBoundsError] If the origin with offset is outside the viewport. + # @rbs (Selenium::WebDriver::WheelActions::ScrollOrigin, Integer, Integer, ?device: nil) -> Selenium::WebDriver::ActionBuilder def scroll_from(scroll_origin, delta_x, delta_y, device: nil) raise TypeError, "#{scroll_origin.inspect} isn't a valid ScrollOrigin" unless scroll_origin.is_a?(ScrollOrigin) @@ -98,6 +102,7 @@ def scroll_from(scroll_origin, delta_x, delta_y, device: nil) private + # @rbs (**Selenium::WebDriver::Element? | Integer? | (Integer | Selenium::WebDriver::Element)? | (Integer | Symbol)?) -> Selenium::WebDriver::ActionBuilder def scroll(**opts) opts[:duration] = default_scroll_duration wheel = wheel_input(opts.delete(:device)) @@ -106,6 +111,7 @@ def scroll(**opts) self end + # @rbs (?nil) -> Selenium::WebDriver::Interactions::WheelInput def wheel_input(name = nil) device(name: name, type: Interactions::WHEEL) || add_wheel_input('wheel') end diff --git a/rb/lib/selenium/webdriver/common/interactions/wheel_input.rb b/rb/lib/selenium/webdriver/common/interactions/wheel_input.rb index d19863188953e..807bdfdec8225 100644 --- a/rb/lib/selenium/webdriver/common/interactions/wheel_input.rb +++ b/rb/lib/selenium/webdriver/common/interactions/wheel_input.rb @@ -27,11 +27,13 @@ module Interactions # class WheelInput < InputDevice + # @rbs (?String) -> void def initialize(name = nil) super @type = Interactions::WHEEL end + # @rbs (**Selenium::WebDriver::Element | Float | Integer | Float | Integer | Selenium::WebDriver::Element | Float | Integer | Symbol | Float) -> void def create_scroll(**opts) opts[:source] = self add_action(Scroll.new(**opts)) diff --git a/rb/lib/selenium/webdriver/common/keys.rb b/rb/lib/selenium/webdriver/common/keys.rb index 58d28b5dda268..e0bca7209dade 100644 --- a/rb/lib/selenium/webdriver/common/keys.rb +++ b/rb/lib/selenium/webdriver/common/keys.rb @@ -111,6 +111,7 @@ module Keys # @api private # + # @rbs (Symbol) -> String def self.[](key) return KEYS[key] if KEYS[key] @@ -121,6 +122,7 @@ def self.[](key) # @api private # + # @rbs (Array[untyped]) -> Array[untyped] def self.encode(keys) keys.map { |key| encode_key(key) } end @@ -129,6 +131,7 @@ def self.encode(keys) # @api private # + # @rbs (String) -> String def self.encode_key(key) case key when Symbol diff --git a/rb/lib/selenium/webdriver/common/log_entry.rb b/rb/lib/selenium/webdriver/common/log_entry.rb index 23615ccaa53c9..a720039bae6fe 100644 --- a/rb/lib/selenium/webdriver/common/log_entry.rb +++ b/rb/lib/selenium/webdriver/common/log_entry.rb @@ -22,6 +22,7 @@ module WebDriver class LogEntry attr_reader :level, :timestamp, :message + # @rbs (String, Integer, String) -> void def initialize(level, timestamp, message) @level = level @timestamp = timestamp diff --git a/rb/lib/selenium/webdriver/common/logger.rb b/rb/lib/selenium/webdriver/common/logger.rb index a7440f326c760..108474524cac4 100644 --- a/rb/lib/selenium/webdriver/common/logger.rb +++ b/rb/lib/selenium/webdriver/common/logger.rb @@ -127,6 +127,7 @@ def debug(message, id: [], &block) # @param [Symbol, Array] id # @yield see #deprecate # + # @rbs (String, ?id: Array[untyped]) -> nil def info(message, id: [], &block) discard_or_log(:info, message, id, &block) end @@ -162,6 +163,7 @@ def warn(message, id: [], &block) # @param [String] reference # @yield appends additional message to end of provided template # + # @rbs (String, ?String, ?id: Symbol, ?reference: String) -> void def deprecate(old, new = nil, id: [], reference: '', &block) id = Array(id) return if @ignored.include?(:deprecations) diff --git a/rb/lib/selenium/webdriver/common/logs.rb b/rb/lib/selenium/webdriver/common/logs.rb index 47c466d15212e..0a2570245e0c9 100644 --- a/rb/lib/selenium/webdriver/common/logs.rb +++ b/rb/lib/selenium/webdriver/common/logs.rb @@ -24,14 +24,17 @@ class Logs # @api private # + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end + # @rbs (Symbol) -> Array[untyped] def get(type) @bridge.log type end + # @rbs () -> Array[untyped] def available_types @bridge.available_log_types end diff --git a/rb/lib/selenium/webdriver/common/manager.rb b/rb/lib/selenium/webdriver/common/manager.rb index 99181d7700f67..d9c806747d3ea 100644 --- a/rb/lib/selenium/webdriver/common/manager.rb +++ b/rb/lib/selenium/webdriver/common/manager.rb @@ -24,6 +24,7 @@ class Manager # @api private # + # @rbs (Selenium::WebDriver::Remote::BiDiBridge) -> void def initialize(bridge) @bridge = bridge end @@ -42,6 +43,7 @@ def initialize(bridge) # @raise [ArgumentError] if :name or :value is not specified # + # @rbs (?Hash[untyped, untyped]) -> nil def add_cookie(opts = {}) raise ArgumentError, 'name is required' unless opts[:name] raise ArgumentError, 'value is required' unless opts[:value] @@ -68,6 +70,7 @@ def add_cookie(opts = {}) # @return [Hash] the cookie, or throws a NoSuchCookieError if it wasn't found. # + # @rbs (String) -> Hash[untyped, untyped]? def cookie_named(name) convert_cookie(@bridge.cookie(name)) end @@ -78,6 +81,7 @@ def cookie_named(name) # @param [String] name the name of the cookie to delete # + # @rbs ((String | Symbol)?) -> nil def delete_cookie(name) @bridge.delete_cookie name end @@ -86,6 +90,7 @@ def delete_cookie(name) # Delete all cookies # + # @rbs () -> nil def delete_all_cookies @bridge.delete_all_cookies end @@ -96,14 +101,17 @@ def delete_all_cookies # @return [Array] list of cookies # + # @rbs () -> Array[untyped] def all_cookies @bridge.cookies.map { |cookie| convert_cookie(cookie) } end + # @rbs () -> Selenium::WebDriver::Timeouts def timeouts @timeouts ||= Timeouts.new(@bridge) end + # @rbs () -> Selenium::WebDriver::Window def window @window ||= Window.new(@bridge) end @@ -112,10 +120,12 @@ def window SECONDS_PER_DAY = 86_400.0 + # @rbs (Integer) -> DateTime def datetime_at(int) DateTime.civil(1970) + (int / SECONDS_PER_DAY) end + # @rbs (DateTime | Time | Float) -> Float def seconds_from(obj) case obj when Time @@ -129,10 +139,12 @@ def seconds_from(obj) end end + # @rbs (String) -> String def strip_port(str) str.split(':', 2).first end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def convert_cookie(cookie) { name: cookie['name'], diff --git a/rb/lib/selenium/webdriver/common/navigation.rb b/rb/lib/selenium/webdriver/common/navigation.rb index 80d2345c486b1..a35d069c20336 100644 --- a/rb/lib/selenium/webdriver/common/navigation.rb +++ b/rb/lib/selenium/webdriver/common/navigation.rb @@ -38,6 +38,7 @@ def to(url) # Move back a single entry in the browser's history. # + # @rbs () -> void def back @bridge.go_back end @@ -46,6 +47,7 @@ def back # Move forward a single entry in the browser's history. # + # @rbs () -> void def forward @bridge.go_forward end @@ -54,6 +56,7 @@ def forward # Refresh the current page. # + # @rbs () -> void def refresh @bridge.refresh end diff --git a/rb/lib/selenium/webdriver/common/network.rb b/rb/lib/selenium/webdriver/common/network.rb index 765ba88097a19..c20e3238cb9a2 100644 --- a/rb/lib/selenium/webdriver/common/network.rb +++ b/rb/lib/selenium/webdriver/common/network.rb @@ -29,21 +29,25 @@ class Network def_delegators :network, :continue_with_auth, :continue_with_request, :continue_with_response + # @rbs (Selenium::WebDriver::Chrome::Driver) -> void def initialize(bridge) @network = BiDi::Network.new(bridge.bidi) @callbacks = {} end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def remove_handler(id) intercept = callbacks[id] network.remove_intercept(intercept['intercept']) callbacks.delete(id) end + # @rbs () -> void def clear_handlers callbacks.each_key { |id| remove_handler(id) } end + # @rbs (?String?, ?String?, *nil | String, ?pattern_type: nil | Symbol) -> Hash[untyped, untyped] def add_authentication_handler(username = nil, password = nil, *filter, pattern_type: nil, &block) selected_block = if username && password @@ -62,6 +66,7 @@ def add_authentication_handler(username = nil, password = nil, *filter, pattern_ ) end + # @rbs (*nil | String, ?pattern_type: nil | Symbol) -> Hash[untyped, untyped] def add_request_handler(*filter, pattern_type: nil, &block) add_handler( :before_request, @@ -73,6 +78,7 @@ def add_request_handler(*filter, pattern_type: nil, &block) ) end + # @rbs (*nil | String, ?pattern_type: nil | Symbol) -> Hash[untyped, untyped] def add_response_handler(*filter, pattern_type: nil, &block) add_handler( :response_started, @@ -86,6 +92,7 @@ def add_response_handler(*filter, pattern_type: nil, &block) private + # @rbs (Symbol, String, Class, Array[untyped], ?pattern_type: nil | Symbol) -> Hash[untyped, untyped] def add_handler(event_type, phase, intercept_type, filter, pattern_type: nil) intercept = network.add_intercept(phases: [phase], url_patterns: [filter].flatten, pattern_type: pattern_type) callback_id = network.on(event_type) do |event| diff --git a/rb/lib/selenium/webdriver/common/options.rb b/rb/lib/selenium/webdriver/common/options.rb index 4b815b9e84703..d0bc01ff2318e 100644 --- a/rb/lib/selenium/webdriver/common/options.rb +++ b/rb/lib/selenium/webdriver/common/options.rb @@ -34,6 +34,7 @@ def chrome(**opts) Chrome::Options.new(**opts) end + # @rbs (**Array[untyped]) -> Selenium::WebDriver::Firefox::Options def firefox(**opts) Firefox::Options.new(**opts) end @@ -43,6 +44,7 @@ def ie(**opts) end alias internet_explorer ie + # @rbs (**Array[untyped] | bool | nil) -> Selenium::WebDriver::Edge::Options def edge(**opts) Edge::Options.new(**opts) end diff --git a/rb/lib/selenium/webdriver/common/platform.rb b/rb/lib/selenium/webdriver/common/platform.rb index c34f14f7f7acc..544dc2d28ba8a 100644 --- a/rb/lib/selenium/webdriver/common/platform.rb +++ b/rb/lib/selenium/webdriver/common/platform.rb @@ -84,6 +84,7 @@ def windows? os == :windows end + # @rbs () -> bool def mac? os == :macosx end diff --git a/rb/lib/selenium/webdriver/common/profile_helper.rb b/rb/lib/selenium/webdriver/common/profile_helper.rb index 64d93d64eaaaa..422ff91641e08 100644 --- a/rb/lib/selenium/webdriver/common/profile_helper.rb +++ b/rb/lib/selenium/webdriver/common/profile_helper.rb @@ -35,6 +35,7 @@ def self.decoded(json) JSON.parse(json).fetch('zip') end + # @rbs () -> String def encoded Zipper.zip(layout_on_disk) end @@ -60,6 +61,7 @@ def create_tmp_copy(directory) tmp_directory end + # @rbs (nil) -> nil def verify_model(model) return unless model diff --git a/rb/lib/selenium/webdriver/common/script.rb b/rb/lib/selenium/webdriver/common/script.rb index 4b58b1bbea2c7..fe28d56cdcf46 100644 --- a/rb/lib/selenium/webdriver/common/script.rb +++ b/rb/lib/selenium/webdriver/common/script.rb @@ -20,21 +20,25 @@ module Selenium module WebDriver class Script + # @rbs (Selenium::WebDriver::Remote::Bridge | Selenium::WebDriver::Remote::BiDiBridge) -> void def initialize(bridge) @log_handler = BiDi::LogHandler.new(bridge.bidi) end # @return [int] id of the handler + # @rbs () -> Integer def add_console_message_handler(&block) @log_handler.add_message_handler('console', &block) end # @return [int] id of the handler + # @rbs () -> void def add_javascript_error_handler(&block) @log_handler.add_message_handler('javascript', &block) end # @param [int] id of the handler previously added + # @rbs (Integer) -> nil def remove_console_message_handler(id) @log_handler.remove_message_handler(id) end diff --git a/rb/lib/selenium/webdriver/common/search_context.rb b/rb/lib/selenium/webdriver/common/search_context.rb index dad7896cbc907..307c0cc8a5a93 100644 --- a/rb/lib/selenium/webdriver/common/search_context.rb +++ b/rb/lib/selenium/webdriver/common/search_context.rb @@ -38,6 +38,7 @@ module SearchContext class << self attr_accessor :extra_finders + # @rbs () -> Hash[untyped, untyped] def finders FINDERS.merge(extra_finders || {}) end @@ -62,6 +63,7 @@ def finders # @raise [Error::NoSuchElementError] if the element doesn't exist # + # @rbs (*Hash[untyped, untyped]) -> Selenium::WebDriver::Element? def find_element(*args) how, what = extract_args(args) @@ -77,6 +79,7 @@ def find_element(*args) # @see SearchContext#find_element # + # @rbs (*Hash[untyped, untyped]) -> Array[untyped] def find_elements(*args) how, what = extract_args(args) @@ -88,6 +91,7 @@ def find_elements(*args) private + # @rbs (Array[untyped]) -> Array[untyped] def extract_args(args) case args.size when 2 diff --git a/rb/lib/selenium/webdriver/common/selenium_manager.rb b/rb/lib/selenium/webdriver/common/selenium_manager.rb index bb5c2520a4c91..777918727b0cd 100644 --- a/rb/lib/selenium/webdriver/common/selenium_manager.rb +++ b/rb/lib/selenium/webdriver/common/selenium_manager.rb @@ -30,6 +30,7 @@ class SeleniumManager class << self attr_writer :bin_path + # @rbs () -> String def bin_path @bin_path ||= '../../../../../bin' end @@ -72,6 +73,7 @@ def run(*command) result end + # @rbs () -> String def platform_location directory = File.expand_path(bin_path, __FILE__) if Platform.windows? diff --git a/rb/lib/selenium/webdriver/common/service.rb b/rb/lib/selenium/webdriver/common/service.rb index fe31efb772e04..baa2ce43d983a 100644 --- a/rb/lib/selenium/webdriver/common/service.rb +++ b/rb/lib/selenium/webdriver/common/service.rb @@ -33,6 +33,7 @@ def chrome(**opts) Chrome::Service.new(**opts) end + # @rbs (**nil) -> Selenium::WebDriver::Firefox::Service def firefox(**opts) Firefox::Service.new(**opts) end @@ -42,6 +43,7 @@ def ie(**opts) end alias internet_explorer ie + # @rbs (**nil) -> Selenium::WebDriver::Edge::Service def edge(**opts) Edge::Service.new(**opts) end @@ -100,6 +102,7 @@ def shutdown_supported self.class::SHUTDOWN_SUPPORTED end + # @rbs () -> String def find_driver_path default_options = WebDriver.const_get("#{self.class.name&.split('::')&.[](2)}::Options").new DriverFinder.new(default_options, self).driver_path diff --git a/rb/lib/selenium/webdriver/common/shadow_root.rb b/rb/lib/selenium/webdriver/common/shadow_root.rb index 3da984038861a..1f97071a977c3 100644 --- a/rb/lib/selenium/webdriver/common/shadow_root.rb +++ b/rb/lib/selenium/webdriver/common/shadow_root.rb @@ -30,6 +30,7 @@ class ShadowRoot # @api private # + # @rbs (Selenium::WebDriver::Remote::Bridge, String) -> void def initialize(bridge, id) @bridge = bridge @id = id @@ -39,6 +40,7 @@ def inspect format '#<%s:0x%x id=%s>', class: self.class, hash: hash * 2, id: @id.inspect end + # @rbs (Selenium::WebDriver::ShadowRoot) -> bool def ==(other) other.is_a?(self.class) && ref == other.ref end @@ -53,6 +55,7 @@ def hash # @see SearchContext # + # @rbs () -> Array[untyped] def ref [:shadow_root, @id] end diff --git a/rb/lib/selenium/webdriver/common/takes_screenshot.rb b/rb/lib/selenium/webdriver/common/takes_screenshot.rb index 8e155eb87b4aa..3ff7c221869c0 100644 --- a/rb/lib/selenium/webdriver/common/takes_screenshot.rb +++ b/rb/lib/selenium/webdriver/common/takes_screenshot.rb @@ -29,6 +29,7 @@ module TakesScreenshot # @api public # + # @rbs (String, ?full_page: bool) -> File? def save_screenshot(png_path, full_page: false) extension = File.extname(png_path).downcase if extension != '.png' @@ -49,6 +50,7 @@ def save_screenshot(png_path, full_page: false) # # @api public + # @rbs (Symbol, ?full_page: bool) -> String? def screenshot_as(format, full_page: false) if full_page && !respond_to?(:save_full_page_screenshot) raise Error::UnsupportedOperationError, "Full Page Screenshots are not supported for #{inspect}" diff --git a/rb/lib/selenium/webdriver/common/target_locator.rb b/rb/lib/selenium/webdriver/common/target_locator.rb index 378fa7ea00c28..af64ca46100ab 100644 --- a/rb/lib/selenium/webdriver/common/target_locator.rb +++ b/rb/lib/selenium/webdriver/common/target_locator.rb @@ -24,6 +24,7 @@ class TargetLocator # @api private # + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end @@ -32,6 +33,7 @@ def initialize(bridge) # switch to the frame with the given id # + # @rbs (String) -> void def frame(id) @bridge.switch_to_frame id end @@ -40,6 +42,7 @@ def frame(id) # switch to the parent frame # + # @rbs () -> void def parent_frame @bridge.switch_to_parent_frame end @@ -51,6 +54,7 @@ def parent_frame # # steep:ignore:start + # @rbs (?Symbol) -> Array[untyped]? def new_window(type = :window) raise ArgumentError, "Valid types are :tab and :window, received: #{type.inspect}" unless %i[window tab].include?(type) @@ -83,6 +87,7 @@ def new_window(type = :window) # A window handle, obtained through Driver#window_handles # + # @rbs (String) -> (bool | Array[untyped] | String)? def window(id) if block_given? original = begin @@ -115,6 +120,7 @@ def window(id) # @return [WebDriver::Element] # + # @rbs () -> Selenium::WebDriver::Element def active_element @bridge.switch_to_active_element end @@ -123,6 +129,7 @@ def active_element # selects either the first frame on the page, or the main document when a page contains iframes. # + # @rbs () -> void def default_content @bridge.switch_to_default_content end @@ -131,6 +138,7 @@ def default_content # switches to the currently active modal dialog for this particular driver instance # + # @rbs () -> Selenium::WebDriver::Alert? def alert Alert.new(@bridge) end diff --git a/rb/lib/selenium/webdriver/common/timeouts.rb b/rb/lib/selenium/webdriver/common/timeouts.rb index 9ec830da55a72..1e8937289270c 100644 --- a/rb/lib/selenium/webdriver/common/timeouts.rb +++ b/rb/lib/selenium/webdriver/common/timeouts.rb @@ -20,6 +20,7 @@ module Selenium module WebDriver class Timeouts + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end @@ -28,6 +29,7 @@ def initialize(bridge) # Gets the amount of time the driver should wait when searching for elements. # + # @rbs () -> Float def implicit_wait Float(@bridge.timeouts['implicit']) / 1000 end @@ -36,6 +38,7 @@ def implicit_wait # Set the amount of time the driver should wait when searching for elements. # + # @rbs (Integer | Float) -> void def implicit_wait=(seconds) @bridge.timeouts = {'implicit' => Integer(seconds * 1000)} end @@ -45,6 +48,7 @@ def implicit_wait=(seconds) # execution before throwing an error. # + # @rbs () -> Float def script Float(@bridge.timeouts['script']) / 1000 end @@ -56,6 +60,7 @@ def script # script will be allowed to run indefinitely. # + # @rbs (Float | Integer) -> Hash[untyped, untyped] def script=(seconds) @bridge.timeouts = {'script' => Integer(seconds * 1000)} end @@ -65,6 +70,7 @@ def script=(seconds) # Gets the amount of time to wait for a page load to complete before throwing an error. # + # @rbs () -> Float def page_load Float(@bridge.timeouts['pageLoad']) / 1000 end @@ -74,6 +80,7 @@ def page_load # If the timeout is negative, page loads can be indefinite. # + # @rbs (Integer) -> void def page_load=(seconds) @bridge.timeouts = {'pageLoad' => Integer(seconds * 1000)} end diff --git a/rb/lib/selenium/webdriver/common/virtual_authenticator/credential.rb b/rb/lib/selenium/webdriver/common/virtual_authenticator/credential.rb index 941440eb64b75..8e0ac08efff23 100644 --- a/rb/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +++ b/rb/lib/selenium/webdriver/common/virtual_authenticator/credential.rb @@ -26,22 +26,27 @@ module Selenium module WebDriver class Credential class << self + # @rbs (**Array[untyped] | String) -> Selenium::WebDriver::Credential def resident(**opts) Credential.new(resident_credential: true, **opts) end + # @rbs (**Array[untyped] | String) -> Selenium::WebDriver::Credential def non_resident(**opts) Credential.new(resident_credential: false, **opts) end + # @rbs (Array[untyped]) -> String def encode(byte_array) Base64.urlsafe_encode64(byte_array&.pack('C*')) end + # @rbs (String) -> Array[untyped] def decode(base64) Base64.urlsafe_decode64(base64).unpack('C*') end + # @rbs (Hash[untyped, untyped]) -> Selenium::WebDriver::Credential def from_json(opts) user_handle = opts['userHandle'] ? decode(opts['userHandle']) : nil new(id: decode(opts['credentialId']), @@ -56,6 +61,7 @@ def from_json(opts) attr_reader :id, :resident_credential, :rp_id, :user_handle, :private_key, :sign_count alias resident_credential? resident_credential + # @rbs (id: Array[untyped], resident_credential: bool, rp_id: String | nil, private_key: Array[untyped] | String, **nil | Array[untyped] | Integer | Array[untyped] | Integer?) -> void def initialize(id:, resident_credential:, rp_id:, private_key:, **opts) @id = id @resident_credential = resident_credential @@ -71,6 +77,7 @@ def initialize(id:, resident_credential:, rp_id:, private_key:, **opts) # @api private # + # @rbs (*untyped) -> Hash[untyped, untyped] def as_json(*) credential_data = {'credentialId' => Credential.encode(id), 'isResidentCredential' => resident_credential?, diff --git a/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb b/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb index bedb4285ae5b0..20f6ddae8ae33 100644 --- a/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +++ b/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb @@ -27,6 +27,7 @@ class VirtualAuthenticator # Use `Driver#add_virtual_authenticator` # + # @rbs (Selenium::WebDriver::Remote::Bridge, String, Selenium::WebDriver::VirtualAuthenticatorOptions) -> void def initialize(bridge, authenticator_id, options) @id = authenticator_id @bridge = bridge @@ -34,11 +35,13 @@ def initialize(bridge, authenticator_id, options) @valid = true end + # @rbs (Selenium::WebDriver::Credential) -> nil def add_credential(credential) credential = credential.as_json @bridge.add_credential credential, @id end + # @rbs () -> Array[untyped] def credentials credential_data = @bridge.credentials @id credential_data.map do |cred| @@ -46,24 +49,29 @@ def credentials end end + # @rbs (Array[untyped] | String) -> void def remove_credential(credential_id) credential_id = Credential.encode(credential_id) if credential_id.instance_of?(Array) @bridge.remove_credential credential_id, @id end + # @rbs () -> void def remove_all_credentials @bridge.remove_all_credentials @id end + # @rbs (bool) -> void def user_verified=(verified) @bridge.user_verified verified, @id end + # @rbs () -> bool def remove! @bridge.remove_virtual_authenticator(@id) @valid = false end + # @rbs () -> bool def valid? @valid end diff --git a/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb b/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb index a6569ff0eebdc..3c25e110713b8 100644 --- a/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +++ b/rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb @@ -34,6 +34,7 @@ class VirtualAuthenticatorOptions alias user_consenting? user_consenting alias user_verified? user_verified + # @rbs (**Symbol | bool) -> void def initialize(**opts) @protocol = opts.delete(:protocol) { :ctap2 } @transport = opts.delete(:transport) { :usb } @@ -49,6 +50,7 @@ def initialize(**opts) # @api private # + # @rbs (*untyped) -> Hash[untyped, untyped] def as_json(*) {'protocol' => PROTOCOL[protocol], 'transport' => TRANSPORT[transport], diff --git a/rb/lib/selenium/webdriver/common/wait.rb b/rb/lib/selenium/webdriver/common/wait.rb index feeecdb4f31c7..60a15118d352a 100644 --- a/rb/lib/selenium/webdriver/common/wait.rb +++ b/rb/lib/selenium/webdriver/common/wait.rb @@ -33,6 +33,7 @@ class Wait # @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Error::NoSuchElementError) # + # @rbs (?Hash[untyped, untyped]) -> void def initialize(opts = {}) @timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT) @interval = opts.fetch(:interval, DEFAULT_INTERVAL) @@ -47,6 +48,7 @@ def initialize(opts = {}) # @return [Object] the result of the block # + # @rbs () -> Selenium::WebDriver::FedCM::Dialog def until end_time = current_time + @timeout last_error = nil @@ -75,6 +77,7 @@ def until private + # @rbs () -> Float def current_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end diff --git a/rb/lib/selenium/webdriver/common/websocket_connection.rb b/rb/lib/selenium/webdriver/common/websocket_connection.rb index 26f02ebc9bf1c..1b7dfde74cd95 100644 --- a/rb/lib/selenium/webdriver/common/websocket_connection.rb +++ b/rb/lib/selenium/webdriver/common/websocket_connection.rb @@ -32,6 +32,7 @@ class WebSocketConnection MAX_LOG_MESSAGE_SIZE = 9999 + # @rbs (url: String) -> void def initialize(url:) @callback_threads = ThreadGroup.new @@ -42,21 +43,25 @@ def initialize(url:) @socket_thread = attach_socket_listener end + # @rbs () -> nil def close @callback_threads.list.each(&:exit) @socket_thread.exit socket.close end + # @rbs () -> Hash[untyped, untyped] def callbacks @callbacks ||= Hash.new { |callbacks, event| callbacks[event] = [] } end + # @rbs (String) -> Integer def add_callback(event, &block) callbacks[event] << block block.object_id end + # @rbs (String, Integer) -> nil def remove_callback(event, id) return if callbacks[event].reject! { |callback| callback.object_id == id } @@ -64,6 +69,7 @@ def remove_callback(event, id) raise Error::WebDriverError, "Callback with ID #{id} does not exist for event #{event}: #{ids}" end + # @rbs (**String | Hash[untyped, untyped]) -> Hash[untyped, untyped] def send_cmd(**payload) id = next_id data = payload.merge(id: id) @@ -80,15 +86,18 @@ def send_cmd(**payload) # We should be thread-safe to use the hash without synchronization # because its keys are WebSocket message identifiers and they should be # unique within a devtools session. + # @rbs () -> Hash[untyped, untyped] def messages @messages ||= {} end + # @rbs () -> void def process_handshake socket.print(ws.to_s) ws << socket.readpartial(1024) end + # @rbs () -> Thread def attach_socket_listener Thread.new do Thread.current.abort_on_exception = true @@ -112,10 +121,12 @@ def attach_socket_listener end end + # @rbs () -> WebSocket::Frame::Incoming::Client def incoming_frame @incoming_frame ||= WebSocket::Frame::Incoming::Client.new(version: ws.version) end + # @rbs (WebSocket::Frame::Incoming::Client) -> Hash[untyped, untyped] def process_frame(frame) message = frame.to_s @@ -129,6 +140,7 @@ def process_frame(frame) message end + # @rbs (Hash[untyped, untyped]) -> Thread def callback_thread(params) Thread.new do Thread.current.abort_on_exception = true @@ -146,10 +158,12 @@ def callback_thread(params) end end + # @rbs () -> Selenium::WebDriver::Wait def wait @wait ||= Wait.new(timeout: RESPONSE_WAIT_TIMEOUT, interval: RESPONSE_WAIT_INTERVAL) end + # @rbs () -> TCPSocket def socket @socket ||= if URI(@url).scheme == 'wss' socket = TCPSocket.new(ws.host, ws.port) @@ -163,10 +177,12 @@ def socket end end + # @rbs () -> WebSocket::Handshake::Client def ws @ws ||= WebSocket::Handshake::Client.new(url: @url) end + # @rbs () -> Integer def next_id @id ||= 0 @id += 1 diff --git a/rb/lib/selenium/webdriver/common/window.rb b/rb/lib/selenium/webdriver/common/window.rb index 0c9356f77e90b..f7950cd085892 100644 --- a/rb/lib/selenium/webdriver/common/window.rb +++ b/rb/lib/selenium/webdriver/common/window.rb @@ -24,6 +24,7 @@ class Window # @api private # + # @rbs (Selenium::WebDriver::Remote::Bridge) -> void def initialize(bridge) @bridge = bridge end @@ -34,6 +35,7 @@ def initialize(bridge) # @param [Selenium::WebDriver::Dimension, #width and #height] dimension The new size. # + # @rbs (Selenium::WebDriver::Dimension) -> void def size=(dimension) unless dimension.respond_to?(:width) && dimension.respond_to?(:height) raise ArgumentError, "expected #{dimension.inspect}:#{dimension.class} " \ @@ -49,6 +51,7 @@ def size=(dimension) # @return [Selenium::WebDriver::Dimension] The size. # + # @rbs () -> Selenium::WebDriver::Dimension def size @bridge.window_size end @@ -59,6 +62,7 @@ def size # @param [Selenium::WebDriver::Point, #x and #y] point The new position. # + # @rbs (Selenium::WebDriver::Point) -> void def position=(point) unless point.respond_to?(:x) && point.respond_to?(:y) raise ArgumentError, "expected #{point.inspect}:#{point.class} " \ @@ -74,6 +78,7 @@ def position=(point) # @return [Selenium::WebDriver::Point] The position. # + # @rbs () -> Selenium::WebDriver::Point def position @bridge.window_position end @@ -84,6 +89,7 @@ def position # @param [Selenium::WebDriver::Rectangle, #x, #y, #width, #height] rectangle The new rect. # + # @rbs (Selenium::WebDriver::Rectangle) -> void def rect=(rectangle) unless %w[x y width height].all? { |val| rectangle.respond_to? val } raise ArgumentError, "expected #{rectangle.inspect}:#{rectangle.class} " \ @@ -102,6 +108,7 @@ def rect=(rectangle) # @return [Selenium::WebDriver::Rectangle] The rectangle. # + # @rbs () -> Selenium::WebDriver::Rectangle def rect @bridge.window_rect end @@ -135,6 +142,7 @@ def move_to(x, y) # Maximize the current window # + # @rbs () -> void def maximize @bridge.maximize_window end @@ -143,6 +151,7 @@ def maximize # Minimize the current window # + # @rbs () -> void def minimize @bridge.minimize_window end @@ -151,6 +160,7 @@ def minimize # Make current window full screen # + # @rbs () -> void def full_screen @bridge.full_screen_window end diff --git a/rb/lib/selenium/webdriver/common/zipper.rb b/rb/lib/selenium/webdriver/common/zipper.rb index d464df500ad9d..ddece84eae767 100644 --- a/rb/lib/selenium/webdriver/common/zipper.rb +++ b/rb/lib/selenium/webdriver/common/zipper.rb @@ -32,6 +32,7 @@ module Zipper EXTENSIONS = %w[.zip .xpi].freeze class << self + # @rbs (String) -> String def unzip(path) destination = Dir.mktmpdir('webdriver-unzip') FileReaper << destination @@ -49,6 +50,7 @@ def unzip(path) destination end + # @rbs (String) -> String def zip(path) with_tmp_zip do |zip| ::Find.find(path) do |file| @@ -60,6 +62,7 @@ def zip(path) end end + # @rbs (String) -> String def zip_file(path) with_tmp_zip do |zip| add_zip_entry zip, path, File.basename(path) @@ -71,6 +74,7 @@ def zip_file(path) private + # @rbs () -> String def with_tmp_zip(&blk) # Don't use Tempfile since it lacks rb_file_s_rename permission on Windows. Dir.mktmpdir do |tmp_dir| @@ -79,6 +83,7 @@ def with_tmp_zip(&blk) end end + # @rbs (Zip::File, String, String) -> void def add_zip_entry(zip, file, entry_name) entry = Zip::Entry.new(zip.name, entry_name) entry.follow_symlinks = true diff --git a/rb/lib/selenium/webdriver/devtools.rb b/rb/lib/selenium/webdriver/devtools.rb index fdc1a194ceee9..d648c932e3952 100644 --- a/rb/lib/selenium/webdriver/devtools.rb +++ b/rb/lib/selenium/webdriver/devtools.rb @@ -28,20 +28,24 @@ class DevTools autoload :Request, 'selenium/webdriver/devtools/request' autoload :Response, 'selenium/webdriver/devtools/response' + # @rbs (url: String, target_type: String) -> void def initialize(url:, target_type:) @ws = WebSocketConnection.new(url: url) @session_id = nil start_session(target_type: target_type) end + # @rbs () -> nil def close @ws.close end + # @rbs () -> Hash[untyped, untyped] def callbacks @ws.callbacks end + # @rbs (String, **nil | String | bool | String? | bool | bool? | String | Hash[untyped, untyped] | Array[untyped]? | (String | Array[untyped])? | String | (String | Integer | Array[untyped])?) -> Hash[untyped, untyped]? def send_cmd(method, **params) data = {method: method, params: params.compact} data[:sessionId] = @session_id if @session_id @@ -51,6 +55,7 @@ def send_cmd(method, **params) message end + # @rbs (Symbol, *nil) -> (Selenium::DevTools::V135::Target | Selenium::DevTools::V135::Page | Selenium::DevTools::V135::CSS | Selenium::DevTools::V135::DOM | Selenium::DevTools::V135::DOMDebugger | Selenium::DevTools::V135::Runtime | Selenium::DevTools::V135::Network | Selenium::DevTools::V135::Fetch) def method_missing(method, *_args) namespace = "Selenium::DevTools::V#{Selenium::DevTools.version}" methods_to_classes = "#{namespace}::METHODS_TO_CLASSES" @@ -81,6 +86,7 @@ def respond_to_missing?(method, *_args) private + # @rbs (target_type: String) -> String? def start_session(target_type:) targets = target.get_targets.dig('result', 'targetInfos') found_target = targets.find { |target| target['type'] == target_type } diff --git a/rb/lib/selenium/webdriver/devtools/console_event.rb b/rb/lib/selenium/webdriver/devtools/console_event.rb index e3d0f56a8cfe3..1747620dfab67 100644 --- a/rb/lib/selenium/webdriver/devtools/console_event.rb +++ b/rb/lib/selenium/webdriver/devtools/console_event.rb @@ -23,6 +23,7 @@ class DevTools class ConsoleEvent attr_accessor :type, :timestamp, :args + # @rbs (type: String, timestamp: Float, args: Array[untyped]) -> void def initialize(type:, timestamp:, args:) @type = type.to_sym @timestamp = Time.at(timestamp / 1000) diff --git a/rb/lib/selenium/webdriver/devtools/exception_event.rb b/rb/lib/selenium/webdriver/devtools/exception_event.rb index 8f0f44dd8ae69..355a80e526681 100644 --- a/rb/lib/selenium/webdriver/devtools/exception_event.rb +++ b/rb/lib/selenium/webdriver/devtools/exception_event.rb @@ -23,6 +23,7 @@ class DevTools class ExceptionEvent attr_accessor :description, :timestamp, :stacktrace + # @rbs (description: String, timestamp: Float, stacktrace: Array[untyped]) -> void def initialize(description:, timestamp:, stacktrace:) @description = description @timestamp = Time.at(timestamp / 1000) diff --git a/rb/lib/selenium/webdriver/devtools/mutation_event.rb b/rb/lib/selenium/webdriver/devtools/mutation_event.rb index c902d4871a78a..d3b0ada334c75 100644 --- a/rb/lib/selenium/webdriver/devtools/mutation_event.rb +++ b/rb/lib/selenium/webdriver/devtools/mutation_event.rb @@ -23,6 +23,7 @@ class DevTools class MutationEvent attr_accessor :element, :attribute_name, :current_value, :old_value + # @rbs (element: Selenium::WebDriver::Element, attribute_name: String, current_value: String, old_value: String) -> void def initialize(element:, attribute_name:, current_value:, old_value:) @element = element @attribute_name = attribute_name diff --git a/rb/lib/selenium/webdriver/devtools/network_interceptor.rb b/rb/lib/selenium/webdriver/devtools/network_interceptor.rb index 95e3236a63fae..13ae787b0d105 100644 --- a/rb/lib/selenium/webdriver/devtools/network_interceptor.rb +++ b/rb/lib/selenium/webdriver/devtools/network_interceptor.rb @@ -38,11 +38,13 @@ class NetworkInterceptor # Typical reason is browser cancelling intercepted requests/responses. INVALID_INTERCEPTION_ID_ERROR_CODE = '-32602' + # @rbs (Selenium::WebDriver::DevTools) -> void def initialize(devtools) @devtools = devtools @lock = Mutex.new end + # @rbs () -> Hash[untyped, untyped] def intercept(&block) devtools.network.on(:loading_failed) { |params| track_cancelled_request(params) } devtools.fetch.on(:request_paused) { |params| request_paused(params, &block) } @@ -59,6 +61,7 @@ def intercept(&block) # We should be thread-safe to use the hash without synchronization # because its keys are interception job identifiers and they should be # unique within a devtools session. + # @rbs () -> Hash[untyped, untyped] def pending_response_requests @pending_response_requests ||= {} end @@ -74,6 +77,7 @@ def track_cancelled_request(data) lock.synchronize { cancelled_requests << data['requestId'] } end + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped]? def request_paused(data, &block) id = data['requestId'] network_id = data['networkId'] @@ -90,10 +94,12 @@ def request_paused(data, &block) # The presence of any of these fields indicate we're at the response stage. # @see https://chromedevtools.github.io/devtools-protocol/tot/Fetch/#event-requestPaused + # @rbs (Hash[untyped, untyped]) -> bool def response?(params) params.key?('responseStatusCode') || params.key?('responseErrorReason') end + # @rbs (String, Hash[untyped, untyped]) -> Hash[untyped, untyped] def intercept_request(id, params, &block) original = DevTools::Request.from(id, params) mutable = DevTools::Request.from(id, params) @@ -109,6 +115,7 @@ def intercept_request(id, params, &block) end end + # @rbs (String, Hash[untyped, untyped]) -> Hash[untyped, untyped]? def intercept_response(id, params) return continue_response(id) unless block_given? @@ -124,11 +131,13 @@ def intercept_response(id, params) end end + # @rbs (String) -> Hash[untyped, untyped]? def continue_request(id) devtools.fetch.continue_request(request_id: id) end alias continue_response continue_request + # @rbs (Selenium::WebDriver::DevTools::Request) -> Hash[untyped, untyped] def mutate_request(request) devtools.fetch.continue_request( request_id: request.id, @@ -141,6 +150,7 @@ def mutate_request(request) ) end + # @rbs (Selenium::WebDriver::DevTools::Response) -> Hash[untyped, untyped] def mutate_response(response) devtools.fetch.fulfill_request( request_id: response.id, @@ -152,12 +162,14 @@ def mutate_response(response) ) end + # @rbs (String) -> String def fetch_response_body(id) devtools.fetch.get_response_body(request_id: id).dig('result', 'body') rescue Error::WebDriverError => e raise unless e.message.start_with?(CANNOT_GET_BODY_ON_REDIRECT_ERROR_CODE) end + # @rbs (String) -> Hash[untyped, untyped]? def with_cancellable_request(network_id) yield rescue Error::WebDriverError => e diff --git a/rb/lib/selenium/webdriver/devtools/pinned_script.rb b/rb/lib/selenium/webdriver/devtools/pinned_script.rb index 53c37351ce856..672239274044d 100644 --- a/rb/lib/selenium/webdriver/devtools/pinned_script.rb +++ b/rb/lib/selenium/webdriver/devtools/pinned_script.rb @@ -23,6 +23,7 @@ class DevTools class PinnedScript attr_accessor :key, :devtools_identifier, :script + # @rbs (String) -> void def initialize(script) @key = SecureRandom.alphanumeric @script = script @@ -32,6 +33,7 @@ def initialize(script) # @api private # + # @rbs () -> String def callable "function __webdriver_#{key}(arguments) { #{script} }" end @@ -40,6 +42,7 @@ def callable # @api private # + # @rbs (*untyped) -> String def to_json(*) %{"return __webdriver_#{key}(arguments)"} end @@ -48,6 +51,7 @@ def to_json(*) # @api private # + # @rbs () -> String def remove "__webdriver_#{key} = undefined" end diff --git a/rb/lib/selenium/webdriver/devtools/request.rb b/rb/lib/selenium/webdriver/devtools/request.rb index ea4c1d33fb3dc..39b7a3148953c 100644 --- a/rb/lib/selenium/webdriver/devtools/request.rb +++ b/rb/lib/selenium/webdriver/devtools/request.rb @@ -29,6 +29,7 @@ class Request # @api private # + # @rbs (String, Hash[untyped, untyped]) -> Selenium::WebDriver::DevTools::Request def self.from(id, params) new( id: id, @@ -39,6 +40,7 @@ def self.from(id, params) ) end + # @rbs (id: String, url: String, method: String, headers: Hash[untyped, untyped], post_data: nil) -> void def initialize(id:, url:, method:, headers:, post_data:) @id = id @url = url @@ -47,6 +49,7 @@ def initialize(id:, url:, method:, headers:, post_data:) @post_data = post_data end + # @rbs (Selenium::WebDriver::DevTools::Request) -> bool def ==(other) self.class == other.class && id == other.id && diff --git a/rb/lib/selenium/webdriver/devtools/response.rb b/rb/lib/selenium/webdriver/devtools/response.rb index 5013b7aee072a..8ccab0f73d351 100644 --- a/rb/lib/selenium/webdriver/devtools/response.rb +++ b/rb/lib/selenium/webdriver/devtools/response.rb @@ -29,6 +29,7 @@ class Response # @api private # + # @rbs (String, String, Hash[untyped, untyped]) -> Selenium::WebDriver::DevTools::Response def self.from(id, encoded_body, params) new( id: id, @@ -40,6 +41,7 @@ def self.from(id, encoded_body, params) ) end + # @rbs (id: String, code: Integer, body: String, headers: Hash[untyped, untyped]) -> void def initialize(id:, code:, body:, headers:) @id = id @code = code @@ -47,6 +49,7 @@ def initialize(id:, code:, body:, headers:) @headers = headers end + # @rbs (Selenium::WebDriver::DevTools::Response) -> bool def ==(other) self.class == other.class && id == other.id && diff --git a/rb/lib/selenium/webdriver/edge.rb b/rb/lib/selenium/webdriver/edge.rb index 0f9e5d3ff1c14..e627a8f1403d9 100644 --- a/rb/lib/selenium/webdriver/edge.rb +++ b/rb/lib/selenium/webdriver/edge.rb @@ -31,6 +31,7 @@ def self.path=(path) @path = path end + # @rbs () -> nil def self.path @path ||= nil end diff --git a/rb/lib/selenium/webdriver/edge/driver.rb b/rb/lib/selenium/webdriver/edge/driver.rb index 7ab091b9d5f6f..b214158958b25 100644 --- a/rb/lib/selenium/webdriver/edge/driver.rb +++ b/rb/lib/selenium/webdriver/edge/driver.rb @@ -30,17 +30,20 @@ module Edge class Driver < Chromium::Driver include LocalDriver + # @rbs (?options: Selenium::WebDriver::Edge::Options, ?service: Selenium::WebDriver::Edge::Service, ?url: nil, **nil) -> void def initialize(options: nil, service: nil, url: nil, **opts) caps, url = initialize_local_driver(options, service, url) super(caps: caps, url: url, **opts) end + # @rbs () -> Symbol def browser :edge end private + # @rbs () -> String def devtools_address "http://#{capabilities['ms:edgeOptions']['debuggerAddress']}" end diff --git a/rb/lib/selenium/webdriver/edge/features.rb b/rb/lib/selenium/webdriver/edge/features.rb index 3b7dff4ef5c50..8fcddecfcf2f2 100644 --- a/rb/lib/selenium/webdriver/edge/features.rb +++ b/rb/lib/selenium/webdriver/edge/features.rb @@ -35,10 +35,12 @@ module Features send_command: [:post, 'session/:session_id/ms/cdp/execute'] }.freeze + # @rbs () -> Hash[untyped, untyped] def command_list EDGE_COMMANDS.merge(CHROMIUM_COMMANDS).merge(self.class::COMMANDS) end + # @rbs (Symbol) -> Array[untyped] def commands(command) command_list[command] end diff --git a/rb/lib/selenium/webdriver/edge/options.rb b/rb/lib/selenium/webdriver/edge/options.rb index 6aa515100b413..2290c0f44ba22 100644 --- a/rb/lib/selenium/webdriver/edge/options.rb +++ b/rb/lib/selenium/webdriver/edge/options.rb @@ -42,10 +42,12 @@ def webview2! private + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def enable_logging(browser_options) browser_options['ms:loggingPrefs'] = @logging_prefs end + # @rbs () -> nil def binary_path Edge.path end diff --git a/rb/lib/selenium/webdriver/edge/service.rb b/rb/lib/selenium/webdriver/edge/service.rb index 3d99635c59f62..55d943cfec536 100644 --- a/rb/lib/selenium/webdriver/edge/service.rb +++ b/rb/lib/selenium/webdriver/edge/service.rb @@ -25,6 +25,7 @@ class Service < WebDriver::Service EXECUTABLE = 'msedgedriver' SHUTDOWN_SUPPORTED = true DRIVER_PATH_ENV_KEY = 'SE_EDGEDRIVER' + # @rbs () -> nil def log return @log unless @log.is_a? String diff --git a/rb/lib/selenium/webdriver/firefox.rb b/rb/lib/selenium/webdriver/firefox.rb index bfa1aadb6329f..c0cb96a836cce 100644 --- a/rb/lib/selenium/webdriver/firefox.rb +++ b/rb/lib/selenium/webdriver/firefox.rb @@ -47,6 +47,7 @@ def self.path=(path) @path = path end + # @rbs () -> nil def self.path @path ||= nil end diff --git a/rb/lib/selenium/webdriver/firefox/driver.rb b/rb/lib/selenium/webdriver/firefox/driver.rb index 704eadd060e93..4e8e9d4d6b49a 100644 --- a/rb/lib/selenium/webdriver/firefox/driver.rb +++ b/rb/lib/selenium/webdriver/firefox/driver.rb @@ -36,11 +36,13 @@ class Driver < WebDriver::Driver include LocalDriver + # @rbs (?options: Selenium::WebDriver::Firefox::Options, ?service: Selenium::WebDriver::Firefox::Service, ?url: nil, **nil) -> void def initialize(options: nil, service: nil, url: nil, **opts) caps, url = initialize_local_driver(options, service, url) super(caps: caps, url: url, **opts) end + # @rbs () -> Symbol def browser :firefox end diff --git a/rb/lib/selenium/webdriver/firefox/features.rb b/rb/lib/selenium/webdriver/firefox/features.rb index e20138ef7aa41..bd969679a50c0 100644 --- a/rb/lib/selenium/webdriver/firefox/features.rb +++ b/rb/lib/selenium/webdriver/firefox/features.rb @@ -29,14 +29,17 @@ module Features full_page_screenshot: [:get, 'session/:session_id/moz/screenshot/full'] }.freeze + # @rbs () -> Hash[untyped, untyped] def command_list FIREFOX_COMMANDS.merge(self.class::COMMANDS) end + # @rbs (Symbol) -> Array[untyped] def commands(command) command_list[command] end + # @rbs (String, bool?) -> String def install_addon(path, temporary) addon = if File.directory?(path) Zipper.zip(path) @@ -49,18 +52,22 @@ def install_addon(path, temporary) execute :install_addon, {}, payload end + # @rbs (String) -> nil def uninstall_addon(id) execute :uninstall_addon, {}, {id: id} end + # @rbs () -> String def full_screenshot execute :full_page_screenshot end + # @rbs (String) -> nil def context=(context) execute :set_context, {}, {context: context} end + # @rbs () -> String def context execute :get_context end diff --git a/rb/lib/selenium/webdriver/firefox/options.rb b/rb/lib/selenium/webdriver/firefox/options.rb index e79e82b1d46a7..4aaf342443c1d 100644 --- a/rb/lib/selenium/webdriver/firefox/options.rb +++ b/rb/lib/selenium/webdriver/firefox/options.rb @@ -56,6 +56,7 @@ class Options < WebDriver::Options # @option opts [Hash] :options A hash for raw options # + # @rbs (?log_level: nil, **Array[untyped]) -> void def initialize(log_level: nil, **opts) @debugger_address = opts.delete(:debugger_address) { true } opts[:accept_insecure_certs] = true unless opts.key?(:accept_insecure_certs) @@ -150,6 +151,7 @@ def enable_android(package: 'org.mozilla.firefox', serial_number: nil, activity: private + # @rbs (Hash[untyped, untyped]) -> void def process_browser_options(browser_options) browser_options['moz:debuggerAddress'] = true if @debugger_address options = browser_options[KEY] @@ -157,6 +159,7 @@ def process_browser_options(browser_options) options['profile'] = @profile if @profile end + # @rbs (nil) -> nil def process_profile(profile) @profile = case profile when nil @@ -168,6 +171,7 @@ def process_profile(profile) end end + # @rbs (Symbol | String) -> bool def camelize?(key) key != 'prefs' end diff --git a/rb/lib/selenium/webdriver/firefox/profile.rb b/rb/lib/selenium/webdriver/firefox/profile.rb index f018c5e2c7541..04b4de51b0577 100644 --- a/rb/lib/selenium/webdriver/firefox/profile.rb +++ b/rb/lib/selenium/webdriver/firefox/profile.rb @@ -71,6 +71,7 @@ def decoded(json) # driver = Selenium::WebDriver.for :firefox, :profile => profile # + # @rbs (?nil) -> void def initialize(model = nil) @model = verify_model(model) @@ -78,6 +79,7 @@ def initialize(model = nil) @extensions = {} end + # @rbs () -> String def layout_on_disk profile_dir = @model ? create_tmp_copy(@model) : Dir.mktmpdir('webdriver-profile') FileReaper << profile_dir @@ -97,6 +99,7 @@ def layout_on_disk # @see http://preferential.mozdev.org/preferences.html # + # @rbs (String, String | Integer) -> (Integer | String) def []=(key, value) unless VALID_PREFERENCE_TYPES.any? { |e| value.is_a? e } raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}" @@ -162,6 +165,7 @@ def set_manual_proxy_preference(key, value) self["network.proxy.#{key}_port"] = Integer(port) if port end + # @rbs (String) -> void def install_extensions(directory) destination = File.join(directory, 'extensions') @@ -171,16 +175,19 @@ def install_extensions(directory) end end + # @rbs () -> Hash[untyped, untyped] def read_model_prefs return {} unless @model read_user_prefs(File.join(@model, 'user.js')) end + # @rbs (String) -> void def delete_extensions_cache(directory) FileUtils.rm_f File.join(directory, 'extensions.cache') end + # @rbs (String) -> void def delete_lock_files(directory) LOCK_FILES.each do |name| FileUtils.rm_f File.join(directory, name) @@ -191,6 +198,7 @@ def extension_name_for(path) File.basename(path, File.extname(path)) end + # @rbs (String) -> void def update_user_prefs_in(directory) path = File.join(directory, 'user.js') prefs = read_user_prefs(path) @@ -203,6 +211,7 @@ def update_user_prefs_in(directory) write_prefs prefs, path end + # @rbs (String) -> Hash[untyped, untyped] def read_user_prefs(path) prefs = {} return prefs unless File.exist?(path) @@ -220,6 +229,7 @@ def read_user_prefs(path) prefs end + # @rbs (Hash[untyped, untyped], String) -> Hash[untyped, untyped] def write_prefs(prefs, path) File.open(path, 'w') do |file| prefs.each do |key, value| diff --git a/rb/lib/selenium/webdriver/firefox/service.rb b/rb/lib/selenium/webdriver/firefox/service.rb index 45fc17a38547d..8e676592269eb 100644 --- a/rb/lib/selenium/webdriver/firefox/service.rb +++ b/rb/lib/selenium/webdriver/firefox/service.rb @@ -26,6 +26,7 @@ class Service < WebDriver::Service SHUTDOWN_SUPPORTED = false DRIVER_PATH_ENV_KEY = 'SE_GECKODRIVER' + # @rbs (?path: nil, ?port: nil, ?log: nil, ?args: nil) -> void def initialize(path: nil, port: nil, log: nil, args: nil) args ||= [] unless args.any? { |arg| arg.include?('--connect-existing') } diff --git a/rb/lib/selenium/webdriver/firefox/util.rb b/rb/lib/selenium/webdriver/firefox/util.rb index 330651891cdde..b6f5a5598faba 100644 --- a/rb/lib/selenium/webdriver/firefox/util.rb +++ b/rb/lib/selenium/webdriver/firefox/util.rb @@ -37,6 +37,7 @@ def app_data_path end end + # @rbs (String) -> nil def stringified?(str) str =~ /^".*"$/ end diff --git a/rb/lib/selenium/webdriver/remote/bidi_bridge.rb b/rb/lib/selenium/webdriver/remote/bidi_bridge.rb index c95ddec538f85..62299cb53c733 100644 --- a/rb/lib/selenium/webdriver/remote/bidi_bridge.rb +++ b/rb/lib/selenium/webdriver/remote/bidi_bridge.rb @@ -23,40 +23,48 @@ module Remote class BiDiBridge < Bridge attr_reader :bidi + # @rbs (Hash[untyped, untyped]) -> Selenium::WebDriver::BiDi def create_session(capabilities) super socket_url = @capabilities[:web_socket_url] @bidi = Selenium::WebDriver::BiDi.new(url: socket_url) end + # @rbs (String) -> Hash[untyped, untyped] def get(url) browsing_context.navigate(url) end + # @rbs () -> Hash[untyped, untyped] def go_back browsing_context.traverse_history(-1) end + # @rbs () -> Hash[untyped, untyped] def go_forward browsing_context.traverse_history(1) end + # @rbs () -> Hash[untyped, untyped] def refresh browsing_context.reload end + # @rbs () -> nil def quit super ensure bidi.close end + # @rbs () -> Array[untyped] def close execute(:close_window).tap { |handles| bidi.close if handles.empty? } end private + # @rbs () -> Selenium::WebDriver::BiDi::BrowsingContext def browsing_context @browsing_context ||= WebDriver::BiDi::BrowsingContext.new(self) end diff --git a/rb/lib/selenium/webdriver/remote/bridge.rb b/rb/lib/selenium/webdriver/remote/bridge.rb index 8be67dcab2230..8c951e065600e 100644 --- a/rb/lib/selenium/webdriver/remote/bridge.rb +++ b/rb/lib/selenium/webdriver/remote/bridge.rb @@ -46,6 +46,7 @@ def locator_converter @locator_converter ||= LocatorConverter.new end + # @rbs () -> Class def element_class @element_class ||= Element end @@ -116,6 +117,7 @@ def browser end end + # @rbs () -> Hash[untyped, untyped] def status execute :status end @@ -129,10 +131,12 @@ def get(url) # timeouts # + # @rbs () -> Hash[untyped, untyped] def timeouts execute :get_timeouts, {} end + # @rbs (Hash[untyped, untyped]) -> nil def timeouts=(timeouts) execute :set_timeout, {}, timeouts end @@ -141,18 +145,22 @@ def timeouts=(timeouts) # alerts # + # @rbs () -> nil def accept_alert execute :accept_alert end + # @rbs () -> nil def dismiss_alert execute :dismiss_alert end + # @rbs (String) -> nil def alert=(keys) execute :send_alert_text, {}, {value: keys.chars, text: keys} end + # @rbs () -> String? def alert_text execute :get_alert_text end @@ -161,22 +169,27 @@ def alert_text # navigation # + # @rbs () -> nil def go_back execute :back end + # @rbs () -> nil def go_forward execute :forward end + # @rbs () -> String def url execute :get_current_url end + # @rbs () -> String def title execute :get_title end + # @rbs () -> String def page_source execute :get_page_source end @@ -191,23 +204,28 @@ def page_source # @return [Hash] Containing 'handle' with the value of the window handle # and 'type' with the value of the created window type # + # @rbs (Symbol) -> Hash[untyped, untyped] def new_window(type) execute :new_window, {}, {type: type} end + # @rbs (String) -> nil def switch_to_window(name) execute :switch_to_window, {}, {handle: name} end + # @rbs (String) -> nil def switch_to_frame(id) id = find_element_by('id', id) if id.is_a? String execute :switch_to_frame, {}, {id: id} end + # @rbs () -> nil def switch_to_parent_frame execute :switch_to_parent_frame end + # @rbs () -> nil def switch_to_default_content switch_to_frame nil end @@ -222,10 +240,12 @@ def quit nil end + # @rbs () -> Array[untyped]? def close execute :close_window end + # @rbs () -> nil def refresh execute :refresh end @@ -234,20 +254,24 @@ def refresh # window handling # + # @rbs () -> Array[untyped] def window_handles execute :get_window_handles end + # @rbs () -> String def window_handle execute :get_window_handle end + # @rbs (Integer, Integer, ?Symbol) -> Hash[untyped, untyped] def resize_window(width, height, handle = :current) raise Error::WebDriverError, 'Switch to desired window before changing its size' unless handle == :current set_window_rect(width: width, height: height) end + # @rbs (?Symbol) -> Selenium::WebDriver::Dimension def window_size(handle = :current) unless handle == :current raise Error::UnsupportedOperationError, @@ -258,10 +282,12 @@ def window_size(handle = :current) Dimension.new data['width'], data['height'] end + # @rbs () -> Hash[untyped, untyped] def minimize_window execute :minimize_window end + # @rbs (?Symbol) -> Hash[untyped, untyped] def maximize_window(handle = :current) unless handle == :current raise Error::UnsupportedOperationError, @@ -271,34 +297,41 @@ def maximize_window(handle = :current) execute :maximize_window end + # @rbs () -> Hash[untyped, untyped] def full_screen_window execute :fullscreen_window end + # @rbs (Integer, Integer) -> Hash[untyped, untyped] def reposition_window(x, y) set_window_rect(x: x, y: y) end + # @rbs () -> Selenium::WebDriver::Point def window_position data = execute :get_window_rect Point.new data['x'], data['y'] end + # @rbs (?x: nil | Integer, ?y: nil | Integer, ?width: Integer | nil, ?height: Integer | nil) -> Hash[untyped, untyped] def set_window_rect(x: nil, y: nil, width: nil, height: nil) params = {x: x, y: y, width: width, height: height} params.update(params) { |_k, v| Integer(v) unless v.nil? } execute :set_window_rect, {}, params end + # @rbs () -> Selenium::WebDriver::Rectangle def window_rect data = execute :get_window_rect Rectangle.new data['x'], data['y'], data['width'], data['height'] end + # @rbs () -> String def screenshot execute :take_screenshot end + # @rbs (String) -> String def element_screenshot(element) execute :take_element_screenshot, id: element end @@ -313,6 +346,7 @@ def execute_script(script, *args) unwrap_script_result result end + # @rbs (String, *Array[untyped] | nil) -> Hash[untyped, untyped] def execute_async_script(script, *args) result = execute :execute_async_script, {}, {script: script, args: args} unwrap_script_result result @@ -322,28 +356,34 @@ def execute_async_script(script, *args) # cookies # + # @rbs () -> Selenium::WebDriver::Manager def manage @manage ||= WebDriver::Manager.new(self) end + # @rbs (Hash[untyped, untyped]) -> nil def add_cookie(cookie) execute :add_cookie, {}, {cookie: cookie} end + # @rbs ((String | Symbol)?) -> nil def delete_cookie(name) raise ArgumentError, 'Cookie name cannot be null or empty' if name.nil? || name.to_s.strip.empty? execute :delete_cookie, name: name end + # @rbs (String) -> Hash[untyped, untyped]? def cookie(name) execute :get_cookie, name: name end + # @rbs () -> Array[untyped] def cookies execute :get_all_cookies end + # @rbs () -> nil def delete_all_cookies execute :delete_all_cookies end @@ -352,37 +392,45 @@ def delete_all_cookies # actions # + # @rbs (?async: bool, ?devices: Array[untyped], ?duration: Integer) -> Selenium::WebDriver::ActionBuilder def action(async: false, devices: [], duration: 250) ActionBuilder.new self, async: async, devices: devices, duration: duration end alias actions action + # @rbs (Array[untyped]) -> nil def send_actions(data) execute :actions, {}, {actions: data} end + # @rbs () -> nil def release_actions execute :release_actions end + # @rbs (?Hash[untyped, untyped]) -> String def print_page(options = {}) execute :print_page, {}, {options: options} end + # @rbs (String) -> nil def click_element(element) execute :element_click, id: element end + # @rbs (String, Array[untyped]) -> nil def send_keys_to_element(element, keys) keys = upload_if_necessary(keys) if @file_detector text = keys.join execute :element_send_keys, {id: element}, {value: text.chars, text: text} end + # @rbs (String) -> nil def clear_element(element) execute :element_clear, id: element end + # @rbs (String) -> nil def submit_element(element) script = "/* submitForm */ var form = arguments[0];\n" \ "while (form.nodeName != \"FORM\" && form.parentNode) {\n " \ @@ -403,27 +451,33 @@ def submit_element(element) # element properties # + # @rbs (String) -> String def element_tag_name(element) execute :get_element_tag_name, id: element end + # @rbs (Selenium::WebDriver::Element, String) -> String def element_attribute(element, name) WebDriver.logger.debug "Using script for :getAttribute of #{name}", id: :script execute_atom :getAttribute, element, name end + # @rbs (String, String) -> String? def element_dom_attribute(element, name) execute :get_element_attribute, id: element, name: name end + # @rbs (String, Symbol) -> String def element_property(element, name) execute :get_element_property, id: element, name: name end + # @rbs (String) -> String def element_aria_role(element) execute :get_element_aria_role, id: element end + # @rbs (String) -> String def element_aria_label(element) execute :get_element_aria_label, id: element end @@ -432,46 +486,55 @@ def element_value(element) element_property element, 'value' end + # @rbs (String) -> String def element_text(element) execute :get_element_text, id: element end + # @rbs (String) -> Selenium::WebDriver::Point def element_location(element) data = execute :get_element_rect, id: element Point.new data['x'], data['y'] end + # @rbs (String) -> Selenium::WebDriver::Rectangle def element_rect(element) data = execute :get_element_rect, id: element Rectangle.new data['x'], data['y'], data['width'], data['height'] end + # @rbs (String) -> Selenium::WebDriver::Point def element_location_once_scrolled_into_view(element) send_keys_to_element(element, ['']) element_location(element) end + # @rbs (String) -> Selenium::WebDriver::Dimension def element_size(element) data = execute :get_element_rect, id: element Dimension.new data['width'], data['height'] end + # @rbs (String) -> bool def element_enabled?(element) execute :is_element_enabled, id: element end + # @rbs (String) -> bool def element_selected?(element) execute :is_element_selected, id: element end + # @rbs (Selenium::WebDriver::Element) -> bool def element_displayed?(element) WebDriver.logger.debug 'Using script for :isDisplayed', id: :script execute_atom :isDisplayed, element end + # @rbs (String, String) -> String def element_value_of_css_property(element, prop) execute :get_element_css_value, id: element, property_name: prop end @@ -480,12 +543,14 @@ def element_value_of_css_property(element, prop) # finding elements # + # @rbs () -> Selenium::WebDriver::Element def active_element Bridge.element_class.new self, element_id_from(execute(:get_active_element)) end alias switch_to_active_element active_element + # @rbs (String, String, ?Array[untyped]) -> Selenium::WebDriver::Element? def find_element_by(how, what, parent_ref = []) how, what = @locator_converter.convert(how, what) @@ -504,6 +569,7 @@ def find_element_by(how, what, parent_ref = []) Bridge.element_class.new self, element_id_from(id) end + # @rbs (String, String, ?Array[untyped]) -> Array[untyped] def find_elements_by(how, what, parent_ref = []) how, what = @locator_converter.convert(how, what) @@ -522,6 +588,7 @@ def find_elements_by(how, what, parent_ref = []) ids.map { |id| Bridge.element_class.new self, element_id_from(id) } end + # @rbs (String) -> Selenium::WebDriver::ShadowRoot? def shadow_root(element) id = execute :get_element_shadow_root, id: element ShadowRoot.new self, shadow_root_id_from(id) @@ -531,31 +598,38 @@ def shadow_root(element) # virtual-authenticator # + # @rbs (Selenium::WebDriver::VirtualAuthenticatorOptions) -> Selenium::WebDriver::VirtualAuthenticator def add_virtual_authenticator(options) authenticator_id = execute :add_virtual_authenticator, {}, options.as_json VirtualAuthenticator.new(self, authenticator_id, options) end + # @rbs (String) -> void def remove_virtual_authenticator(id) execute :remove_virtual_authenticator, {authenticatorId: id} end + # @rbs (Hash[untyped, untyped], String) -> Hash[untyped, untyped]? def add_credential(credential, id) execute :add_credential, {authenticatorId: id}, credential end + # @rbs (String) -> Array[untyped] def credentials(authenticator_id) execute :get_credentials, {authenticatorId: authenticator_id} end + # @rbs (String, String) -> Hash[untyped, untyped] def remove_credential(credential_id, authenticator_id) execute :remove_credential, {credentialId: credential_id, authenticatorId: authenticator_id} end + # @rbs (String) -> Hash[untyped, untyped] def remove_all_credentials(authenticator_id) execute :remove_all_credentials, {authenticatorId: authenticator_id} end + # @rbs (bool, String) -> Hash[untyped, untyped] def user_verified(verified, authenticator_id) execute :set_user_verified, {authenticatorId: authenticator_id}, {isUserVerified: verified} end @@ -564,42 +638,52 @@ def user_verified(verified, authenticator_id) # federated-credential management # + # @rbs () -> nil def cancel_fedcm_dialog execute :cancel_fedcm_dialog end + # @rbs (Integer) -> nil def select_fedcm_account(index) execute :select_fedcm_account, {}, {accountIndex: index} end + # @rbs () -> String? def fedcm_dialog_type execute :get_fedcm_dialog_type end + # @rbs () -> String? def fedcm_title execute(:get_fedcm_title).fetch('title') end + # @rbs () -> nil def fedcm_subtitle execute(:get_fedcm_title).fetch('subtitle', nil) end + # @rbs () -> Array[untyped]? def fedcm_account_list execute :get_fedcm_account_list end + # @rbs (bool) -> nil def fedcm_delay(enabled) execute :set_fedcm_delay, {}, {enabled: enabled} end + # @rbs () -> nil def reset_fedcm_cooldown execute :reset_fedcm_cooldown end + # @rbs () -> nil def click_fedcm_dialog_button execute :click_fedcm_dialog_button, {}, {dialogButton: 'ConfirmIdpLoginContinue'} end + # @rbs () -> nil def bidi msg = 'BiDi must be enabled by setting #web_socket_url to true in options class' raise(WebDriver::Error::WebDriverError, msg) @@ -635,6 +719,7 @@ def execute(command, opts = {}, command_hash = nil) http.call(verb, path, command_hash)['value'] end + # @rbs () -> URI::RFC2396_Parser def escaper @escaper ||= defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER end @@ -662,10 +747,12 @@ def unwrap_script_result(arg) end end + # @rbs (Hash[untyped, untyped]) -> nil def element_id_from(id) id['ELEMENT'] || id[Bridge.element_class::ELEMENT_KEY] end + # @rbs (Hash[untyped, untyped]) -> nil def shadow_root_id_from(id) id[ShadowRoot::ROOT_KEY] end diff --git a/rb/lib/selenium/webdriver/remote/bridge/locator_converter.rb b/rb/lib/selenium/webdriver/remote/bridge/locator_converter.rb index 6c1065b9a5a25..2a180726ccb8a 100644 --- a/rb/lib/selenium/webdriver/remote/bridge/locator_converter.rb +++ b/rb/lib/selenium/webdriver/remote/bridge/locator_converter.rb @@ -31,6 +31,7 @@ class LocatorConverter # @param [String] what # + # @rbs (String, String) -> Array[untyped] def convert(how, what) how = SearchContext.finders[how.to_sym] || how @@ -63,6 +64,7 @@ def convert(how, what) # @see https://mathiasbynens.be/notes/css-escapes # + # @rbs (String) -> String def escape_css(string) string = string.gsub(ESCAPE_CSS_REGEXP) { |match| "\\#{match}" } string = "\\#{UNICODE_CODE_POINT + Integer(string[0])} #{string[1..]}" if string[0]&.match?(/[[:digit:]]/) diff --git a/rb/lib/selenium/webdriver/remote/capabilities.rb b/rb/lib/selenium/webdriver/remote/capabilities.rb index 76e3c8b1a5b24..99c43e82b296e 100644 --- a/rb/lib/selenium/webdriver/remote/capabilities.rb +++ b/rb/lib/selenium/webdriver/remote/capabilities.rb @@ -159,6 +159,7 @@ def merge!(other) end end + # @rbs () -> nil def proxy @capabilities[:proxy] end @@ -183,6 +184,7 @@ def timeouts=(timeouts) @capabilities[:timeouts] = timeouts end + # @rbs () -> Integer def implicit_timeout timeouts[:implicit] end @@ -192,6 +194,7 @@ def implicit_timeout=(timeout) timeouts[:implicit] = timeout end + # @rbs () -> Integer def page_load_timeout timeouts[:page_load] || timeouts[:pageLoad] end @@ -201,6 +204,7 @@ def page_load_timeout=(timeout) timeouts[:page_load] = timeout end + # @rbs () -> Integer def script_timeout timeouts[:script] end diff --git a/rb/lib/selenium/webdriver/remote/driver.rb b/rb/lib/selenium/webdriver/remote/driver.rb index 806b5b8035a81..e999eec62dacb 100644 --- a/rb/lib/selenium/webdriver/remote/driver.rb +++ b/rb/lib/selenium/webdriver/remote/driver.rb @@ -30,6 +30,7 @@ class Driver < WebDriver::Driver include DriverExtensions::HasSessionId include DriverExtensions::HasFileDownloads + # @rbs (?capabilities: nil, ?options: Selenium::WebDriver::Firefox::Options, ?service: nil, ?url: String, **nil) -> void def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts) raise ArgumentError, "Can not set :service object on #{self.class}" if service @@ -44,10 +45,12 @@ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts) private + # @rbs () -> String def devtools_url capabilities['se:cdp'] end + # @rbs () -> Integer def devtools_version cdp_version = capabilities['se:cdpVersion']&.split('.')&.first raise Error::WebDriverError, 'DevTools is not supported by the Remote Server' unless cdp_version @@ -55,6 +58,7 @@ def devtools_version Integer(cdp_version) end + # @rbs (Selenium::WebDriver::Firefox::Options, nil) -> Hash[untyped, untyped] def process_options(options, capabilities) if options && capabilities msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options" diff --git a/rb/lib/selenium/webdriver/remote/features.rb b/rb/lib/selenium/webdriver/remote/features.rb index 638ced4d60ed4..7abc9217c0767 100644 --- a/rb/lib/selenium/webdriver/remote/features.rb +++ b/rb/lib/selenium/webdriver/remote/features.rb @@ -28,18 +28,22 @@ module Features delete_downloadable_files: [:delete, 'session/:session_id/se/files'] }.freeze + # @rbs (Hash[untyped, untyped]) -> Hash[untyped, untyped] def add_commands(commands) @command_list = command_list.merge(commands) end + # @rbs () -> Hash[untyped, untyped] def command_list @command_list ||= REMOTE_COMMANDS end + # @rbs (Symbol) -> Array[untyped] def commands(command) command_list[command] end + # @rbs (String) -> String def upload(local_file) unless File.file?(local_file) WebDriver.logger.error("File detector only works with files. #{local_file.inspect} isn`t a file!", @@ -50,6 +54,7 @@ def upload(local_file) execute :upload_file, {}, {file: Zipper.zip_file(local_file)} end + # @rbs (Array[untyped]) -> Array[untyped] def upload_if_necessary(keys) local_files = keys.first&.split("\n")&.filter_map { |key| @file_detector.call(Array(key)) } return keys unless local_files&.any? @@ -58,14 +63,17 @@ def upload_if_necessary(keys) Array(keys.join("\n")) end + # @rbs () -> Hash[untyped, untyped] def downloadable_files execute :get_downloadable_files end + # @rbs (String) -> Hash[untyped, untyped] def download_file(name) execute :download_file, {}, {name: name} end + # @rbs () -> nil def delete_downloadable_files execute :delete_downloadable_files end diff --git a/rb/lib/selenium/webdriver/remote/response.rb b/rb/lib/selenium/webdriver/remote/response.rb index 83f58ff5a308f..0d0e3dfb20d55 100644 --- a/rb/lib/selenium/webdriver/remote/response.rb +++ b/rb/lib/selenium/webdriver/remote/response.rb @@ -60,6 +60,7 @@ def assert_ok raise Error::ServerError, self end + # @rbs (Selenium::WebDriver::Error::NoSuchAlertError | Selenium::WebDriver::Error::UnknownError, String, String) -> void def add_cause(ex, error, backtrace) cause = Error::WebDriverError.new backtrace = backtrace_from_remote(backtrace) if backtrace.is_a?(Array) diff --git a/rb/lib/selenium/webdriver/support/abstract_event_listener.rb b/rb/lib/selenium/webdriver/support/abstract_event_listener.rb index 6660a60f3a858..06bd751b13944 100644 --- a/rb/lib/selenium/webdriver/support/abstract_event_listener.rb +++ b/rb/lib/selenium/webdriver/support/abstract_event_listener.rb @@ -74,8 +74,10 @@ def before_execute_script(script, driver) end def after_execute_script(script, driver) end + # @rbs (Selenium::WebDriver::Driver) -> nil def before_quit(driver) end + # @rbs (Selenium::WebDriver::Driver) -> nil def after_quit(driver) end def before_close(driver) end diff --git a/rb/lib/selenium/webdriver/support/escaper.rb b/rb/lib/selenium/webdriver/support/escaper.rb index 78ee487736d83..69c27f60ce8e2 100644 --- a/rb/lib/selenium/webdriver/support/escaper.rb +++ b/rb/lib/selenium/webdriver/support/escaper.rb @@ -21,6 +21,7 @@ module Selenium module WebDriver module Support module Escaper + # @rbs (String) -> String def self.escape(str) if str.include?('"') && str.include?("'") parts = str.split('"', -1).map { |part| %("#{part}") } diff --git a/rb/lib/selenium/webdriver/support/event_firing_bridge.rb b/rb/lib/selenium/webdriver/support/event_firing_bridge.rb index f793129494423..d361061bce019 100644 --- a/rb/lib/selenium/webdriver/support/event_firing_bridge.rb +++ b/rb/lib/selenium/webdriver/support/event_firing_bridge.rb @@ -25,6 +25,7 @@ module Support # class EventFiringBridge + # @rbs (Selenium::WebDriver::Remote::Bridge, Selenium::WebDriver::Support::AbstractEventListener) -> void def initialize(delegate, listener) @delegate = delegate @@ -93,6 +94,7 @@ def execute_script(script, *args) end end + # @rbs () -> nil def quit dispatch(:quit, driver) { @delegate.quit } end @@ -108,10 +110,12 @@ def create_element(ref) Element.new @delegate, ref end + # @rbs () -> Selenium::WebDriver::Driver def driver @driver ||= Driver.new(bridge: self) end + # @rbs (Symbol, *Selenium::WebDriver::Driver) -> nil def dispatch(name, *args) @listener.__send__(:"before_#{name}", *args) returned = yield @@ -120,6 +124,7 @@ def dispatch(name, *args) returned end + # @rbs (Symbol, *untyped, **untyped) -> (Symbol | Proc | Hash[untyped, untyped]) def method_missing(meth, ...) # rubocop:disable Style/MissingRespondToMissing @delegate.__send__(meth, ...) end diff --git a/rb/lib/selenium/webdriver/support/guards/guard.rb b/rb/lib/selenium/webdriver/support/guards/guard.rb index 21187fa45d6af..f6d78f4b847e4 100644 --- a/rb/lib/selenium/webdriver/support/guards/guard.rb +++ b/rb/lib/selenium/webdriver/support/guards/guard.rb @@ -41,6 +41,7 @@ def initialize(guarded, type, guards = nil) @guarded[:reason] = @reason end + # @rbs () -> String def message details = case reason when Integer diff --git a/rb/lib/selenium/webdriver/support/relative_locator.rb b/rb/lib/selenium/webdriver/support/relative_locator.rb index 1067005d5d35f..b1161d3ecd37d 100644 --- a/rb/lib/selenium/webdriver/support/relative_locator.rb +++ b/rb/lib/selenium/webdriver/support/relative_locator.rb @@ -27,10 +27,12 @@ module Support class RelativeLocator KEYS = %w[above below left right near distance].freeze + # @rbs (Hash[untyped, untyped]) -> void def initialize(locator) @filters, @root = locator.partition { |how, _| KEYS.include?(how) }.map(&:to_h) end + # @rbs () -> Hash[untyped, untyped] def as_json { relative: { diff --git a/rb/lib/selenium/webdriver/support/select.rb b/rb/lib/selenium/webdriver/support/select.rb index f5ad753f14914..3f989614e9ec1 100644 --- a/rb/lib/selenium/webdriver/support/select.rb +++ b/rb/lib/selenium/webdriver/support/select.rb @@ -25,6 +25,7 @@ class Select # @param [Element] element The select element to use # + # @rbs (Selenium::WebDriver::Element) -> void def initialize(element) tag_name = element.tag_name @@ -40,6 +41,7 @@ def initialize(element) # @return [Boolean] # + # @rbs () -> bool def multiple? @multi end @@ -50,6 +52,7 @@ def multiple? # @return [Array] # + # @rbs () -> Array[untyped] def options @element.find_elements tag_name: 'option' end @@ -60,6 +63,7 @@ def options # @return [Array] # + # @rbs () -> Array[untyped] def selected_options options.select(&:selected?) end @@ -71,6 +75,7 @@ def selected_options # @return [Element] # + # @rbs () -> Selenium::WebDriver::Element def first_selected_option option = options.find(&:selected?) return option if option @@ -98,6 +103,7 @@ def first_selected_option # @param [String] what What value to find the option by. # + # @rbs (Symbol, String | Integer) -> Array[untyped]? def select_by(how, what) case how when :text @@ -121,6 +127,7 @@ def select_by(how, what) # @see Select#select_by # + # @rbs (Symbol, String | Integer) -> Array[untyped]? def deselect_by(how, what) case how when :text @@ -140,6 +147,7 @@ def deselect_by(how, what) # @raise [Error::UnsupportedOperationError] if the element does not support multiple selections. # + # @rbs () -> Array[untyped]? def select_all raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select' unless multiple? @@ -152,6 +160,7 @@ def select_all # @raise [Error::UnsupportedOperationError] if the element does not support multiple selections. # + # @rbs () -> Array[untyped]? def deselect_all raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select' unless multiple? @@ -160,6 +169,7 @@ def deselect_all private + # @rbs (String) -> Array[untyped]? def select_by_text(text) opts = find_by_text text @@ -168,6 +178,7 @@ def select_by_text(text) raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}" end + # @rbs (Integer) -> nil def select_by_index(index) opts = find_by_index index @@ -176,6 +187,7 @@ def select_by_index(index) raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}" end + # @rbs (String) -> Array[untyped]? def select_by_value(value) opts = find_by_value value @@ -184,6 +196,7 @@ def select_by_value(value) raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}" end + # @rbs (String) -> Array[untyped]? def deselect_by_text(text) raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple? @@ -194,6 +207,7 @@ def deselect_by_text(text) raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}" end + # @rbs (String) -> Array[untyped]? def deselect_by_value(value) raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple? @@ -204,6 +218,7 @@ def deselect_by_value(value) raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}" end + # @rbs (Integer) -> nil def deselect_by_index(index) raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple? @@ -214,16 +229,19 @@ def deselect_by_index(index) raise Error::NoSuchElementError, "cannot locate option with index: #{index}" end + # @rbs (Selenium::WebDriver::Element) -> nil def select_option(option) raise Error::UnsupportedOperationError, 'You may not select a disabled option' unless option.enabled? option.click unless option.selected? end + # @rbs (Selenium::WebDriver::Element) -> nil def deselect_option(option) option.click if option.selected? end + # @rbs (Array[untyped]) -> Array[untyped]? def select_options(opts) if multiple? opts.each { |o| select_option o } @@ -232,6 +250,7 @@ def select_options(opts) end end + # @rbs (Array[untyped]) -> Array[untyped] def deselect_options(opts) if multiple? opts.each { |o| deselect_option o } @@ -240,6 +259,7 @@ def deselect_options(opts) end end + # @rbs (String) -> Array[untyped] def find_by_text(text) xpath = ".//option[normalize-space(.) = #{Escaper.escape text}]" opts = @element.find_elements(xpath: xpath) @@ -259,10 +279,12 @@ def find_by_text(text) candidates.select { |option| text == option.text } end + # @rbs (Integer) -> Array[untyped] def find_by_index(index) options.select { |option| option.property(:index) == index } end + # @rbs (String) -> Array[untyped] def find_by_value(value) @element.find_elements(xpath: ".//option[@value = #{Escaper.escape value}]") end diff --git a/rb/rbs_collection.lock.yaml b/rb/rbs_collection.lock.yaml index ce3878d164f4f..5cc203d70cbfc 100644 --- a/rb/rbs_collection.lock.yaml +++ b/rb/rbs_collection.lock.yaml @@ -25,6 +25,22 @@ gems: version: '0' source: type: stdlib +- name: diff-lcs + version: '1.5' + source: + type: git + name: ruby/gem_rbs_collection + revision: eb6867fdb70e82e3aac6b51623ed1b6760c3c072 + remote: https://github.com/ruby/gem_rbs_collection.git + repo_dir: gems +- name: digest + version: '0' + source: + type: stdlib +- name: erb + version: '0' + source: + type: stdlib - name: fileutils version: '0' source: @@ -49,6 +65,10 @@ gems: version: '0' source: type: stdlib +- name: openssl + version: '0' + source: + type: stdlib - name: optparse version: '0' source: @@ -69,6 +89,10 @@ gems: revision: 01361bb0fd6e2f3e2da2b11a733ffc938b9047c4 remote: https://github.com/ruby/gem_rbs_collection.git repo_dir: gems +- name: prism + version: 1.4.0 + source: + type: rubygems - name: rack version: '2.2' source: @@ -93,6 +117,10 @@ gems: revision: 01361bb0fd6e2f3e2da2b11a733ffc938b9047c4 remote: https://github.com/ruby/gem_rbs_collection.git repo_dir: gems +- name: rbs-trace + version: 0.5.1 + source: + type: rubygems - name: regexp_parser version: '2.8' source: @@ -121,6 +149,18 @@ gems: revision: 01361bb0fd6e2f3e2da2b11a733ffc938b9047c4 remote: https://github.com/ruby/gem_rbs_collection.git repo_dir: gems +- name: singleton + version: '0' + source: + type: stdlib +- name: socket + version: '0' + source: + type: stdlib +- name: stringio + version: '0' + source: + type: stdlib - name: tempfile version: '0' source: @@ -129,6 +169,18 @@ gems: version: '0' source: type: stdlib +- name: webmock + version: '3.19' + source: + type: git + name: ruby/gem_rbs_collection + revision: eb6867fdb70e82e3aac6b51623ed1b6760c3c072 + remote: https://github.com/ruby/gem_rbs_collection.git + repo_dir: gems +- name: webrick + version: 1.9.1 + source: + type: rubygems - name: yard version: '0.9' source: diff --git a/rb/sig/lib/selenium/webdriver.rbs b/rb/sig/lib/selenium/webdriver.rbs index 147911acb6a0a..7fb3dfc385850 100644 --- a/rb/sig/lib/selenium/webdriver.rbs +++ b/rb/sig/lib/selenium/webdriver.rbs @@ -1,34 +1,3 @@ -module Selenium - module WebDriver - class Point - attr_reader x: Integer - attr_reader y: Integer - - def initialize: (Integer x, Integer y) -> void - end - - class Dimension - attr_reader width: Integer - attr_reader height: Integer - - def initialize: (Integer width, Integer height) -> void - end - - class Rectangle - attr_reader x: Integer - attr_reader y: Integer - attr_reader width: Integer - attr_reader height: Integer - - def initialize: (Integer x, Integer y, Integer width, Integer height) -> void - end - - @root: String - - def self.root: () -> String - - def self.for: (*untyped args) -> untyped - - def self.logger: (**String | Symbol opts) -> WebDriver::Logger - end +module Selenium::WebDriver + def self.logger: (**nil) -> Selenium::WebDriver::Logger end diff --git a/rb/sig/lib/selenium/webdriver/chrome.rbs b/rb/sig/lib/selenium/webdriver/chrome.rbs index f1d605c834bb9..3c9876fc333ee 100644 --- a/rb/sig/lib/selenium/webdriver/chrome.rbs +++ b/rb/sig/lib/selenium/webdriver/chrome.rbs @@ -1,13 +1,3 @@ -module Selenium - module WebDriver - module Chrome - self.@path: String - - @path: String - - def self.path=: (String path) -> String - - def self.path: () -> String? - end - end +module Selenium::WebDriver::Chrome + def self.path: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/chrome/driver.rbs b/rb/sig/lib/selenium/webdriver/chrome/driver.rbs index 92653102f9a90..e337b8b97b657 100644 --- a/rb/sig/lib/selenium/webdriver/chrome/driver.rbs +++ b/rb/sig/lib/selenium/webdriver/chrome/driver.rbs @@ -1,17 +1,5 @@ -module Selenium - module WebDriver - module Chrome - class Driver < Chromium::Driver - include LocalDriver +class Selenium::WebDriver::Chrome::Driver + def initialize: (?options: Selenium::WebDriver::Chrome::Options, ?service: Selenium::WebDriver::Chrome::Service, ?url: nil, **nil) -> void - def initialize: (?options: untyped?, ?service: untyped?, ?url: untyped?, **untyped opts) -> void - - def browser: () -> Symbol - - private - - def devtools_address: () -> String - end - end - end + def browser: () -> Symbol end diff --git a/rb/sig/lib/selenium/webdriver/chrome/features.rbs b/rb/sig/lib/selenium/webdriver/chrome/features.rbs index ab3e9c85707e4..46baf31202653 100644 --- a/rb/sig/lib/selenium/webdriver/chrome/features.rbs +++ b/rb/sig/lib/selenium/webdriver/chrome/features.rbs @@ -1,16 +1,5 @@ -module Selenium - module WebDriver - module Chrome - module Features - include WebDriver::Chromium::Features +module Selenium::WebDriver::Chrome::Features + def commands: (Symbol) -> Array[untyped] - CHROME_COMMANDS: Hash[Symbol, Array[Symbol | String]] - COMMANDS: Hash[Symbol, Array[Symbol | String]] - - def command_list: -> Hash[Symbol, Array[Symbol | String]] - - def commands: (Symbol command) -> Array[Symbol | String] - end - end - end + def command_list: () -> Hash[untyped, untyped] end diff --git a/rb/sig/lib/selenium/webdriver/chrome/options.rbs b/rb/sig/lib/selenium/webdriver/chrome/options.rbs index eae4c2feab36f..08c99aa87fe2c 100644 --- a/rb/sig/lib/selenium/webdriver/chrome/options.rbs +++ b/rb/sig/lib/selenium/webdriver/chrome/options.rbs @@ -1,17 +1,3 @@ -module Selenium - module WebDriver - module Chrome - class Options < Chromium::Options - KEY: String - - BROWSER: String - - private - - def enable_logging: (untyped browser_options) -> untyped - - def binary_path: () -> untyped - end - end - end +class Selenium::WebDriver::Chrome::Options + def binary_path: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/chrome/service.rbs b/rb/sig/lib/selenium/webdriver/chrome/service.rbs index a8fa6e98d4bc0..c592c4263403a 100644 --- a/rb/sig/lib/selenium/webdriver/chrome/service.rbs +++ b/rb/sig/lib/selenium/webdriver/chrome/service.rbs @@ -1,19 +1,3 @@ -module Selenium - module WebDriver - module Chrome - class Service < WebDriver::Service - DRIVER_PATH_ENV_KEY: String - - @log: untyped - - DEFAULT_PORT: Integer - - EXECUTABLE: String - - SHUTDOWN_SUPPORTED: bool - - def log: () -> untyped - end - end - end +class Selenium::WebDriver::Chrome::Service + def log: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/chromium/options.rbs b/rb/sig/lib/selenium/webdriver/chromium/options.rbs index 9d0262127ce75..e58285dc66af5 100644 --- a/rb/sig/lib/selenium/webdriver/chromium/options.rbs +++ b/rb/sig/lib/selenium/webdriver/chromium/options.rbs @@ -1,53 +1,9 @@ -module Selenium - module WebDriver - module Chromium - class Options < WebDriver::Options - include _Options +class Selenium::WebDriver::Chromium::Options + def initialize: (?profile: nil, **Array[untyped]) -> void + | (?profile: nil, **nil) -> void - @profile: untyped + def process_browser_options: (Hash[untyped, untyped]) -> void - @options: untyped - - @logging_prefs: untyped - - @encoded_extensions: untyped - - @extensions: untyped - - attr_accessor profile: untyped - - attr_accessor logging_prefs: untyped - - CAPABILITIES: Hash[Symbol, String] - - attr_reader extensions: untyped - - def initialize: (?profile: untyped?, **untyped opts) -> void - - def add_extension: (untyped path) -> untyped - - def extensions=: (untyped extensions) -> untyped - - def add_encoded_extension: (untyped encoded) -> untyped - - def add_argument: (untyped arg) -> untyped - - def add_preference: (untyped name, untyped value) -> untyped - - def add_emulation: (**untyped opts) -> untyped - - def enable_android: (?package: String, ?serial_number: untyped?, ?use_running_app: untyped?, ?activity: untyped?) -> untyped - - def process_browser_options: (untyped browser_options) -> untyped? - - def binary_path: () -> untyped - - def encode_extension: (untyped path) -> untyped - - def validate_extension: (untyped path) -> untyped - - def camelize?: (untyped key) -> untyped - end - end - end + def camelize?: (Symbol) -> bool + | (String) -> bool end diff --git a/rb/sig/lib/selenium/webdriver/common/child_process.rbs b/rb/sig/lib/selenium/webdriver/common/child_process.rbs index 69785847b71eb..930dcf380b69b 100644 --- a/rb/sig/lib/selenium/webdriver/common/child_process.rbs +++ b/rb/sig/lib/selenium/webdriver/common/child_process.rbs @@ -1,51 +1,16 @@ -module Selenium - module WebDriver - class ChildProcess - @command: untyped +class Selenium::WebDriver::ChildProcess + def exited?: () -> bool - @detach: untyped + def waitpid2: (Integer, ?Integer) -> nil + | (Integer, ?Integer) -> Array[untyped] - @pid: untyped + def poll_for_exit: (Integer) -> nil - @status: untyped + def self.build: (*String) -> Selenium::WebDriver::ChildProcess - @io: untyped + def initialize: (*String) -> void - TimeoutError: untyped + def start: () -> nil - SIGTERM: String - - SIGKILL: String - - POLL_INTERVAL: Float - - attr_accessor detach: untyped - - attr_writer io: untyped - - def self.build: (*untyped command) -> untyped - - def initialize: (*untyped command) -> void - - def io: () -> untyped - - def start: () -> untyped - - def stop: (?Integer timeout) -> untyped - - def alive?: () -> untyped - - def exited?: () -> (false | untyped) - - def poll_for_exit: (untyped timeout) -> untyped - - def wait: () -> (nil | untyped) - - private - - def terminate: (untyped pid) -> untyped - - def kill: (untyped pid) -> untyped - end - end + def io: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/common/driver.rbs b/rb/sig/lib/selenium/webdriver/common/driver.rbs index 8a95acc35109a..f483ba344a8ce 100644 --- a/rb/sig/lib/selenium/webdriver/common/driver.rbs +++ b/rb/sig/lib/selenium/webdriver/common/driver.rbs @@ -1,81 +1,19 @@ -module Selenium - module WebDriver - class Driver - include SearchContext +class Selenium::WebDriver::Driver + def get: (String) -> nil - include TakesScreenshot + def navigate: () -> Selenium::WebDriver::Navigation - @devtools: untyped - @navigate: untyped + def quit: () -> nil - @script: untyped - @service_manager: untyped + def self.for: (Symbol, ?Hash[untyped, untyped]) -> Selenium::WebDriver::Chrome::Driver - def self.for: (untyped browser, Hash[untyped, untyped] opts) -> untyped + def service_url: (Selenium::WebDriver::Chrome::Service) -> URI::HTTP - def initialize: (?bridge: Support::EventFiringBridge? bridge, ?listener: Support::AbstractEventListener? listener, **untyped opts) -> void + def initialize: (?bridge: nil, ?listener: nil, **Hash[untyped, untyped] | URI::HTTP) -> void - def inspect: () -> String + def create_bridge: (caps: Hash[untyped, untyped], url: URI::HTTP, ?http_client: nil) -> Selenium::WebDriver::Remote::Bridge - def network: -> Network + def add_extensions: (Symbol) -> Array[untyped] - def status: () -> Hash[untyped, untyped] - - def navigate: () -> Navigation - - def switch_to: () -> TargetLocator - - def manage: () -> Manager - - def action: (**untyped opts) -> ActionBuilder - - def get: (String url) -> untyped - - def current_url: () -> String - - def title: () -> String - - def page_source: () -> String - - def quit: () -> WebDriver::Remote::Response? - - def close: () -> WebDriver::Remote::Response? - - def window_handles: () -> Array[String] - - def window_handle: () -> String - - def execute_script: (String script, *untyped args) -> untyped - - def execute_async_script: (String script, *untyped args) -> untyped - - def add_virtual_authenticator: (untyped options) -> VirtualAuthenticator - - alias first find_element - - alias all find_elements - - alias script execute_script - - def []: (String | Hash[untyped, untyped] sel) -> Element - - def browser: () -> Symbol - - def capabilities: () -> untyped - - def ref: () -> ::Array[:driver | nil] - - private - - attr_reader bridge: untyped - - def create_bridge: (caps: untyped, url: untyped, ?http_client: untyped) -> untyped - - def service_url: (untyped service) -> untyped - - def screenshot: () -> untyped - - def add_extensions: (String browser) -> void - end - end + def execute_script: (String, *nil) -> void end diff --git a/rb/sig/lib/selenium/webdriver/common/driver_finder.rbs b/rb/sig/lib/selenium/webdriver/common/driver_finder.rbs index fc17ee073d3ee..5557c7cd750ab 100644 --- a/rb/sig/lib/selenium/webdriver/common/driver_finder.rbs +++ b/rb/sig/lib/selenium/webdriver/common/driver_finder.rbs @@ -1,26 +1,13 @@ -module Selenium - module WebDriver - class DriverFinder - @options: untyped +class Selenium::WebDriver::DriverFinder + def initialize: (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service) -> void - @paths: untyped - @service: untyped + def browser_path?: () -> bool - def initialize: (untyped options,untyped service) -> void + def browser_path: () -> String - def self.path: (untyped options, untyped klass) -> untyped + def paths: () -> Hash[untyped, untyped] - def browser_path: -> untyped + def to_args: () -> Array[untyped] - def browser_path?: -> untyped - - def driver_path: -> untyped - - private - - def paths: -> untyped - - def to_args: -> Array[String] - end - end + def driver_path: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/common/error.rbs b/rb/sig/lib/selenium/webdriver/common/error.rbs index 224ee6ee29cee..b2bbcdbd4e9dc 100644 --- a/rb/sig/lib/selenium/webdriver/common/error.rbs +++ b/rb/sig/lib/selenium/webdriver/common/error.rbs @@ -1,106 +1,10 @@ -module Selenium - module WebDriver - module Error - def self.for_error: (String? error) -> Class? - - SUPPORT_MSG: String - - ERROR_URL: String - - URLS: Hash[Symbol?, String] - - class WebDriverError < StandardError - def initialize: (?String | Array[String] msg) -> void - - def class_name: -> Symbol? - end - - class NoSuchElementError < WebDriverError - end - - class NoSuchFrameError < WebDriverError - end - - class UnknownCommandError < WebDriverError - end - - class StaleElementReferenceError < WebDriverError - end - - class DetachedShadowRootError < WebDriverError - end - - class InvalidElementStateError < WebDriverError - end - - class UnknownError < WebDriverError - end - - class JavascriptError < WebDriverError - end - - class TimeoutError < WebDriverError - end - - class NoSuchWindowError < WebDriverError - end - - class NoSuchShadowRootError < WebDriverError - end - - class InvalidCookieDomainError < WebDriverError - end - - class UnableToSetCookieError < WebDriverError - end - - class NoSuchAlertError < WebDriverError - end - - class ScriptTimeoutError < WebDriverError - end - - class InvalidSelectorError < WebDriverError - end - - class SessionNotCreatedError < WebDriverError - end - - class MoveTargetOutOfBoundsError < WebDriverError - end - - class ElementNotInteractableError < WebDriverError - end - - class InsecureCertificateError < WebDriverError - end - - class InvalidArgumentError < WebDriverError - end - - class NoSuchCookieError < WebDriverError - end - - class UnableToCaptureScreenError < WebDriverError - end - - class InvalidSessionIdError < WebDriverError - end - - class UnexpectedAlertOpenError < WebDriverError - end - - class UnknownMethodError < WebDriverError - end - - class ElementClickInterceptedError < WebDriverError - end +module Selenium::WebDriver::Error + def self.for_error: (nil) -> nil + | (String) -> Class +end - class UnsupportedOperationError < WebDriverError - end +class Selenium::WebDriver::Error::WebDriverError + def initialize: (?String) -> void - class NoSuchDriverError < WebDriverError - end - end - end + def class_name: () -> Symbol end diff --git a/rb/sig/lib/selenium/webdriver/common/local_driver.rbs b/rb/sig/lib/selenium/webdriver/common/local_driver.rbs index ef1ac98c8feb9..9a04a38a983da 100644 --- a/rb/sig/lib/selenium/webdriver/common/local_driver.rbs +++ b/rb/sig/lib/selenium/webdriver/common/local_driver.rbs @@ -1,11 +1,5 @@ -module Selenium - module WebDriver - module LocalDriver - include _Driver +module Selenium::WebDriver::LocalDriver + def initialize_local_driver: (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service, nil) -> Array[untyped] - def initialize_local_driver: (untyped options, untyped service, untyped url) -> Array[untyped] - - def process_options: (untyped options, untyped service) -> untyped - end - end + def process_options: (Selenium::WebDriver::Chrome::Options, Selenium::WebDriver::Chrome::Service) -> Hash[untyped, untyped] end diff --git a/rb/sig/lib/selenium/webdriver/common/logger.rbs b/rb/sig/lib/selenium/webdriver/common/logger.rbs index 69a167e4b9276..2176106fe4366 100644 --- a/rb/sig/lib/selenium/webdriver/common/logger.rbs +++ b/rb/sig/lib/selenium/webdriver/common/logger.rbs @@ -1,42 +1,7 @@ -module Selenium - module WebDriver - class Logger +class Selenium::WebDriver::Logger + def debug: (String, ?id: Array[untyped]) -> nil + | (String, ?id: Symbol) -> nil - @allowed: Array[Symbol] - @first_warning: bool - - @ignored: Array[Symbol] - @logger: ::Logger - - def initialize: (?::String progname, ?default_level: Symbol? default_level, ?ignored: Array[Symbol]? ignored, ?allowed: Array[Symbol]? allowed) -> void - - def level=: (Symbol level) -> Symbol - - def output=: (String io) -> ::Logger - - def io: () -> IO - - def ignore: (*Symbol | Array[Symbol] ids) -> Array[Symbol] - - def allow: (*Symbol | Array[Symbol] ids) -> Array[Symbol] - - def debug: (String ?message, ?id: Symbol | Array[Symbol] id) ?{ () -> void } -> void - - def info: (String message, ?id: Symbol | Array[Symbol] id) ?{ () -> void } -> void - - def error: (String message, ?id: Symbol | Array[Symbol] id) ?{ () -> void } -> void - - def warn: (String message, ?id: Symbol | Array[Symbol] id) ?{ () -> void } -> void - - def deprecate: (String old, ?String? new, ?id: Symbol | Array[Symbol] id, ?reference: String reference) ?{ () -> void } -> untyped - - def debug?: () -> bool - - private - - def create_logger: (String name, level: Symbol level) -> ::Logger - - def discard_or_log: (Symbol level, String message, (Symbol | Array[::Symbol]) | [(Symbol | Array[Symbol])] id) ?{ () -> void } -> untyped - end - end + def discard_or_log: (Symbol, String, Array[untyped]) -> nil + | (Symbol, String, Symbol) -> nil end diff --git a/rb/sig/lib/selenium/webdriver/common/navigation.rbs b/rb/sig/lib/selenium/webdriver/common/navigation.rbs index 4c31e52a3fe7c..d8afef620d653 100644 --- a/rb/sig/lib/selenium/webdriver/common/navigation.rbs +++ b/rb/sig/lib/selenium/webdriver/common/navigation.rbs @@ -1,15 +1,5 @@ -module Selenium - module WebDriver - class Navigation - def initialize: (untyped bridge) -> void +class Selenium::WebDriver::Navigation + def initialize: (Selenium::WebDriver::Remote::Bridge) -> void - def to: (String url) -> untyped - - def back: () -> untyped - - def forward: () -> untyped - - def refresh: () -> untyped - end - end + def to: (String) -> nil end diff --git a/rb/sig/lib/selenium/webdriver/common/options.rbs b/rb/sig/lib/selenium/webdriver/common/options.rbs index d2fe0ccd30b20..f70f77a92d198 100644 --- a/rb/sig/lib/selenium/webdriver/common/options.rbs +++ b/rb/sig/lib/selenium/webdriver/common/options.rbs @@ -1,66 +1,40 @@ -module Selenium - module WebDriver - class Options - @options: Hash[untyped, untyped] +class Selenium::WebDriver::Options + def self.chrome: (**Array[untyped]) -> Selenium::WebDriver::Chrome::Options + | (**nil) -> Selenium::WebDriver::Chrome::Options - W3C_OPTIONS: Array[Symbol] + def initialize: (**Array[untyped]) -> void + | (**nil) -> void - GRID_OPTIONS: Array[Symbol] + def as_json: (*untyped) -> Hash[untyped, untyped] - BROWSER: Symbol + def process_w3c_options: (Hash[untyped, untyped]) -> Hash[untyped, untyped] - KEY: untyped + def w3c?: (Symbol) -> bool - CAPABILITIES: Hash[String | Symbol, String | Numeric | bool?] + def generate_as_json: (String, ?camelize_keys: bool) -> String + | (Array[untyped], ?camelize_keys: bool) -> Array[untyped] + | (Hash[untyped, untyped], ?camelize_keys: bool) -> Hash[untyped, untyped] - attr_reader self.driver_path: String + def process_json_hash: (Hash[untyped, untyped], bool) -> Hash[untyped, untyped] - def self.chrome: (**String | Symbol | Integer | bool opts) -> Chrome::Options + def convert_json_key: (Symbol, ?camelize: bool) -> String + | (String, ?camelize: bool) -> String - def self.firefox: (**String | Symbol | Integer | bool opts) -> Firefox::Options - - def self.ie: (**String | Symbol | Integer | bool opts) -> IE::Options - - alias self.internet_explorer self.ie - - def self.edge: (**String | Symbol | Integer | bool opts) -> Edge::Options - - alias self.microsoftedge self.edge - - def self.safari: (**String | Symbol | Integer | bool opts) -> Safari::Options - - def self.set_capabilities: () -> untyped - - attr_accessor options: Hash[String | Symbol, String | Numeric | bool?] - - def initialize: (Hash[String | Symbol, String | Numeric | bool] opts) -> void - - def add_option: (String | Symbol name, String | Numeric | bool? value) -> (String | Numeric | bool)? - - def ==: (untyped other) -> bool - - alias eql? == - - def as_json: (*untyped) -> untyped - - private - - def w3c?: (untyped key) -> untyped + def camel_case: (String) -> String +end - def process_w3c_options: (untyped options) -> untyped +class Selenium::WebDriver::Chrome::Options + def self.set_capabilities: () -> void - def process_browser_options: (untyped _browser_options) -> nil + def browser_name: () -> String - def camelize?: (untyped _key) -> true + def browser_version: () -> nil - def generate_as_json: (Array[untyped] | Hash[untyped, untyped] | String | Symbol value, ?camelize_keys: bool) - -> (Array[untyped] | Hash[untyped, untyped] | String | Symbol) + def binary: () -> nil - def process_json_hash: (Hash[untyped, untyped] value, bool camelize_keys) -> Hash[untyped, untyped] + def proxy: () -> nil - def convert_json_key: (String | Symbol key, camelize: bool) -> String + def binary=: (String) -> String - def camel_case: (String str) -> String - end - end + def browser_version=: (nil) -> nil end diff --git a/rb/sig/lib/selenium/webdriver/common/platform.rbs b/rb/sig/lib/selenium/webdriver/common/platform.rbs index 294c6a5110aec..eee33169de034 100644 --- a/rb/sig/lib/selenium/webdriver/common/platform.rbs +++ b/rb/sig/lib/selenium/webdriver/common/platform.rbs @@ -1,62 +1,31 @@ -module Selenium - module WebDriver - # @api private - module Platform - @home: untyped +module Selenium::WebDriver::Platform + def self.ci: () -> nil - @engine: untyped + def self.os: () -> Symbol - @os: untyped + def self.localhost: () -> String - def self?.home: () -> untyped + def self.jruby?: () -> bool - def self?.engine: () -> untyped + def self.engine: () -> Symbol - def self?.os: () -> untyped + def self.windows?: () -> bool - def self?.ci: () -> Symbol? + def self.truffleruby?: () -> bool - def self?.jruby?: () -> untyped + def self.cygwin_path: (String, ?only_cygwin: bool, **nil) -> String - def self?.truffleruby?: () -> untyped + def self.cygwin?: () -> bool - def self?.ruby_version: () -> untyped + def self.assert_executable: (String) -> void - def self?.windows?: () -> untyped + def self.assert_file: (String) -> void - def self?.mac?: () -> untyped + def self.exit_hook: () -> void - def self?.linux?: () -> untyped + def self.interfaces: () -> Array[untyped] - def self?.wsl?: () -> untyped + def self.ip: () -> String - def self?.cygwin?: () -> untyped - - def self?.null_device: () -> untyped - - def self?.wrap_in_quotes_if_necessary: (untyped str) -> (String | untyped) - - def self?.cygwin_path: (untyped path, **untyped opts) -> untyped - - def self?.unix_path: (untyped path) -> untyped - - def self?.windows_path: (untyped path) -> untyped - - def self?.make_writable: (untyped file) -> untyped - - def self?.assert_file: (untyped path) -> untyped? - - def self?.assert_executable: (untyped path) -> untyped? - - def self?.exit_hook: () { () -> untyped } -> untyped - - def self?.localhost: () -> untyped - - def self?.ip: () -> untyped - - def self?.interfaces: () -> untyped - - def unix?: -> untyped - end - end + def self.null_device: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/common/port_prober.rbs b/rb/sig/lib/selenium/webdriver/common/port_prober.rbs index 1d45cd15321d7..72325d8b1fc06 100644 --- a/rb/sig/lib/selenium/webdriver/common/port_prober.rbs +++ b/rb/sig/lib/selenium/webdriver/common/port_prober.rbs @@ -1,11 +1,5 @@ -module Selenium - module WebDriver - class PortProber - def self.above: (untyped port) -> untyped +class Selenium::WebDriver::PortProber + def self.above: (Integer) -> Integer - IGNORED_ERRORS: untyped - - def self.free?: (untyped port) -> untyped - end - end + def self.free?: (Integer) -> bool end diff --git a/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs b/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs index c73ec88f61487..d4b09720f95df 100644 --- a/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs +++ b/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs @@ -1,30 +1,13 @@ -module Selenium - module WebDriver - class SeleniumManager - include _Platform - include Open3 +class Selenium::WebDriver::SeleniumManager + def self.binary_paths: (*String) -> Hash[untyped, untyped] - self.@bin_path: String + def self.binary: () -> String - self.@binary: String + def self.run: (*String) -> Hash[untyped, untyped] - attr_writer self.bin_path: String + def self.execute_command: (*String) -> Array[untyped] - def self.bin_path: () -> String + def self.parse_result_and_log: (String) -> Hash[untyped, untyped] - def self.binary_paths: (*String arguments) -> Hash[untyped, Array[String]] - - private - - def self.generate_command: (untyped binary, untyped options) -> untyped - - def self.binary: () -> String - - def self.validate_location: (untyped location) -> untyped - - def self.run: (String | Array[String] command) -> Hash[String, Array[String]] - - def self.platform_location: -> String - end - end + def self.validate_command_result: (Array[untyped], Process::Status, Hash[untyped, untyped], String) -> void end diff --git a/rb/sig/lib/selenium/webdriver/common/service.rbs b/rb/sig/lib/selenium/webdriver/common/service.rbs index da5a793919e55..8035a051e31ce 100644 --- a/rb/sig/lib/selenium/webdriver/common/service.rbs +++ b/rb/sig/lib/selenium/webdriver/common/service.rbs @@ -1,65 +1,11 @@ -module Selenium - module WebDriver - class Service - SHUTDOWN_SUPPORTED: untyped +class Selenium::WebDriver::Service + def self.chrome: (**nil) -> Selenium::WebDriver::Chrome::Service - DEFAULT_PORT: untyped + def initialize: (?path: nil, ?port: nil, ?log: nil, ?args: nil) -> void - DRIVER_PATH_ENV_KEY: String + def env_path: () -> nil - self.@driver_path: untyped + def launch: () -> Selenium::WebDriver::ServiceManager - @executable_path: untyped - - @host: untyped - - @port: untyped - - @log: untyped - - @args: untyped - - attr_reader self.driver_path: untyped - - def self.chrome: (**untyped opts) -> untyped - - def self.firefox: (**untyped opts) -> untyped - - def self.ie: (**untyped opts) -> untyped - - alias self.internet_explorer self.ie - - def self.edge: (**untyped opts) -> untyped - - alias self.microsoftedge self.edge - - alias self.msedge self.edge - - def self.safari: (**untyped opts) -> untyped - - def self.driver_path=: (untyped path) -> untyped - - attr_accessor host: untyped - - attr_accessor executable_path: untyped - - attr_accessor port: untyped - - attr_accessor log: untyped - - attr_accessor args: untyped - - def env_path: -> String? - - alias extra_args args - - def initialize: (?path: untyped?, ?port: untyped?, ?log: untyped?, ?args: untyped?) -> void - - def find_driver_path: -> untyped - - def launch: () -> untyped - - def shutdown_supported: () -> untyped - end - end + def shutdown_supported: () -> bool end diff --git a/rb/sig/lib/selenium/webdriver/common/service_manager.rbs b/rb/sig/lib/selenium/webdriver/common/service_manager.rbs index d677aa1e58fdc..692eea398884a 100644 --- a/rb/sig/lib/selenium/webdriver/common/service_manager.rbs +++ b/rb/sig/lib/selenium/webdriver/common/service_manager.rbs @@ -1,61 +1,29 @@ -module Selenium - module WebDriver - class ServiceManager - @executable_path: untyped +class Selenium::WebDriver::ServiceManager + def stop: () -> void - @host: untyped + def process_exited?: () -> bool - @port: untyped + def stop_server: () -> void - @io: untyped + def connect_to_server: () -> Net::HTTPOK - @extra_args: untyped + def stop_process: () -> nil - @shutdown_supported: untyped + def initialize: (Selenium::WebDriver::Chrome::Service) -> void - @uri: untyped + def start: () -> void - @process: untyped + def process_running?: () -> nil - @socket_lock: untyped + def socket_lock: () -> Selenium::WebDriver::SocketLock - START_TIMEOUT: Integer + def find_free_port: () -> void - SOCKET_LOCK_TIMEOUT: Integer + def start_process: () -> void - STOP_TIMEOUT: Integer + def build_process: (*String) -> Selenium::WebDriver::ChildProcess - def initialize: (untyped config) -> void + def connect_until_stable: () -> nil - def start: () -> untyped - - def stop: () -> untyped - - def uri: () -> untyped - - private - - def build_process: (*untyped command) -> untyped - - def connect_to_server: () { (untyped) -> untyped } -> untyped - - def find_free_port: () -> untyped - - def start_process: () -> untyped - - def stop_process: () -> (nil | untyped) - - def stop_server: () -> untyped - - def process_running?: () -> untyped - - def process_exited?: () -> untyped - - def connect_until_stable: () -> untyped? - - def cannot_connect_error_text: () -> String - - def socket_lock: () -> untyped - end - end + def uri: () -> URI::HTTP end diff --git a/rb/sig/lib/selenium/webdriver/common/socket_lock.rbs b/rb/sig/lib/selenium/webdriver/common/socket_lock.rbs index 4a806f52f805e..73f5bc3718a3b 100644 --- a/rb/sig/lib/selenium/webdriver/common/socket_lock.rbs +++ b/rb/sig/lib/selenium/webdriver/common/socket_lock.rbs @@ -1,27 +1,15 @@ -module Selenium - module WebDriver - class SocketLock - @port: untyped +class Selenium::WebDriver::SocketLock + def initialize: (Integer, Integer) -> void - @server: untyped + def locked: () -> nil - @timeout: untyped + def lock: () -> void - def initialize: (untyped port, untyped timeout) -> void + def current_time: () -> Float - def locked: () { () -> untyped } -> untyped + def can_lock?: () -> bool - private + def did_lock?: () -> bool - def lock: () -> untyped? - - def current_time: () -> untyped - - def release: () -> untyped - - def can_lock?: () -> untyped - - def did_lock?: () -> untyped - end - end + def release: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/common/socket_poller.rbs b/rb/sig/lib/selenium/webdriver/common/socket_poller.rbs index 631b443064a31..5cf8885cf5554 100644 --- a/rb/sig/lib/selenium/webdriver/common/socket_poller.rbs +++ b/rb/sig/lib/selenium/webdriver/common/socket_poller.rbs @@ -1,37 +1,15 @@ -module Selenium - module WebDriver - class SocketPoller - @host: untyped +class Selenium::WebDriver::SocketPoller + def initialize: (String, Integer, ?Integer, ?Float) -> void - @port: untyped + def connected?: () -> bool - @timeout: untyped + def with_timeout: () -> bool - @interval: untyped + def current_time: () -> Float - def initialize: (untyped host, untyped port, ?::Integer timeout, ?::Float interval) -> void + def listening?: () -> bool - def connected?: () -> untyped + def socket_writable?: (Socket) -> Socket - def closed?: () -> untyped - - private - - CONNECT_TIMEOUT: Integer - - NOT_CONNECTED_ERRORS: Array[singleton(::Errno::ECONNREFUSED) | singleton(::Errno::ENOTCONN) | singleton(::Errno::EPERM)] - - CONNECTED_ERRORS: Array[singleton(::Errno::EISCONN) | singleton(::Errno::EINVAL) | singleton(::Errno::EALREADY)] - - def listening?: () -> untyped - - def socket_writable?: (untyped sock) -> untyped - - def conn_completed?: (untyped sock) -> untyped - - def with_timeout: () { () -> untyped } -> bool - - def current_time: () -> untyped - end - end + def conn_completed?: (Socket) -> bool end diff --git a/rb/sig/lib/selenium/webdriver/common/wait.rbs b/rb/sig/lib/selenium/webdriver/common/wait.rbs index 1e1c888a9edf2..d913d54dda531 100644 --- a/rb/sig/lib/selenium/webdriver/common/wait.rbs +++ b/rb/sig/lib/selenium/webdriver/common/wait.rbs @@ -1,25 +1,7 @@ -module Selenium - module WebDriver - class Wait - @timeout: Numeric +class Selenium::WebDriver::Wait + def initialize: (?Hash[untyped, untyped]) -> void - @interval: Numeric + def until: () -> Selenium::WebDriver::FedCM::Dialog - @message: String - - @ignored: Array[Exception] - - DEFAULT_TIMEOUT: Integer - - DEFAULT_INTERVAL: Float - - def initialize: (Hash[untyped, untyped] opts) -> void - - def until: () { () -> untyped } -> untyped - - private - - def current_time: () -> untyped - end - end + def current_time: () -> Float end diff --git a/rb/sig/lib/selenium/webdriver/remote/bridge.rbs b/rb/sig/lib/selenium/webdriver/remote/bridge.rbs index 8da1a8dac805d..4922ab6b89821 100644 --- a/rb/sig/lib/selenium/webdriver/remote/bridge.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/bridge.rbs @@ -1,277 +1,53 @@ -module Selenium - module WebDriver - module Remote - class Bridge - include _CommandList - include _Features +class Selenium::WebDriver::Remote::Bridge + def get: (String) -> nil - @bidi: WebDriver::BiDi - @http: untyped + def execute: (Symbol, ?Hash[untyped, untyped], ?Hash[untyped, untyped]) -> nil + | (Symbol, ?Hash[untyped, untyped], ?nil) -> nil + | (Symbol, ?Hash[untyped, untyped], ?Hash[untyped, untyped]) -> Hash[untyped, untyped] + | (Symbol, ?Hash[untyped, untyped], ?nil) -> String + | (Symbol, ?Hash[untyped, untyped], ?nil) -> Hash[untyped, untyped] + | (Symbol, ?Hash[untyped, untyped], ?nil) -> Array[untyped] - @file_detector: untyped + def session_id: () -> String - @session_id: untyped + def fedcm_title: () -> nil + | () -> String - @capabilities: untyped + def fedcm_subtitle: () -> nil - @browser: untyped + def fedcm_dialog_type: () -> nil + | () -> String - @manage: untyped + def fedcm_account_list: () -> nil + | () -> Array[untyped] - @escaper: untyped + def select_fedcm_account: (Integer) -> nil - include Atoms + def cancel_fedcm_dialog: () -> nil - PORT: Integer + def quit: () -> nil - attr_accessor http: untyped + def initialize: (url: URI::HTTP, ?http_client: nil) -> void - attr_accessor file_detector: untyped + def self.locator_converter: () -> Selenium::WebDriver::Remote::Bridge::LocatorConverter - attr_reader capabilities: untyped + def create_session: (Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Bridge - def initialize: (url: String | URI, ?http_client: untyped?) -> void + def prepare_capabilities_payload: (Hash[untyped, untyped]) -> Hash[untyped, untyped] - def bidi: -> WebDriver::Error::WebDriverError + def commands: (Symbol) -> Array[untyped] - def cancel_fedcm_dialog: -> nil + def command_list: () -> Hash[untyped, untyped] - def click_fedcm_dialog_button: -> nil + def browser: () -> Symbol - def create_session: (untyped capabilities) -> untyped + def execute_script: (String, *nil) -> nil - extend WebDriver::Chrome::Features + def unwrap_script_result: (nil) -> nil - extend WebDriver::Firefox::Features + def click_fedcm_dialog_button: () -> nil - extend WebDriver::Edge::Features + def fedcm_delay: (bool) -> nil - extend WebDriver::Safari::Features - - def fedcm_account_list: -> Array[Hash[untyped, untyped]] - - def fedcm_dialog_type: -> String - - def fedcm_subtitle: -> String? - - def fedcm_title: -> String - - def reset_fedcm_cooldown: -> nil - - def select_fedcm_account: (Integer index) -> nil - - def session_id: () -> untyped - - def browser: () -> untyped - - def fedcm_delay: -> bool - - def status: () -> untyped - - def get: (untyped url) -> untyped - - def timeouts: () -> untyped - - def timeouts=: (untyped timeouts) -> untyped - - def accept_alert: () -> untyped - - def dismiss_alert: () -> untyped - - def alert=: (untyped keys) -> untyped - - def alert_text: () -> untyped - - def go_back: () -> untyped - - def go_forward: () -> untyped - - def url: () -> untyped - - def title: () -> untyped - - def page_source: () -> untyped - - def new_window: (untyped type) -> untyped - - def switch_to_window: (untyped name) -> untyped - - def switch_to_frame: (untyped id) -> untyped - - def switch_to_parent_frame: () -> untyped - - def switch_to_default_content: () -> untyped - - QUIT_ERRORS: ::Array[untyped] - - def quit: () -> untyped - - def close: () -> untyped - - def refresh: () -> untyped - - def window_handles: () -> untyped - - def window_handle: () -> untyped - - def resize_window: (untyped width, untyped height, ?::Symbol handle) -> untyped - - def window_size: (?::Symbol handle) -> untyped - - def minimize_window: () -> untyped - - def maximize_window: (?::Symbol handle) -> untyped - - def full_screen_window: () -> untyped - - def reposition_window: (untyped x, untyped y) -> untyped - - def window_position: () -> untyped - - def set_window_rect: (?x: untyped?, ?y: untyped?, ?width: untyped?, ?height: untyped?) -> untyped - - def window_rect: () -> untyped - - def screenshot: () -> untyped - - def element_screenshot: (untyped element) -> untyped - - def local_storage_item: (untyped key, ?untyped? value) -> untyped - - def remove_local_storage_item: (untyped key) -> untyped - - def local_storage_keys: () -> untyped - - def clear_local_storage: () -> untyped - - def local_storage_size: () -> untyped - - def session_storage_item: (untyped key, ?untyped? value) -> untyped - - def remove_session_storage_item: (untyped key) -> untyped - - def session_storage_keys: () -> untyped - - def clear_session_storage: () -> untyped - - def session_storage_size: () -> untyped - - def execute_script: (untyped script, *untyped args) -> untyped - - def execute_async_script: (untyped script, *untyped args) -> untyped - - def manage: () -> untyped - - def add_cookie: (untyped cookie) -> untyped - - def delete_cookie: (untyped name) -> untyped - - def cookie: (untyped name) -> untyped - - def cookies: () -> untyped - - def delete_all_cookies: () -> untyped - - def action: (?async: bool, ?devices: untyped, ?duration: ::Integer) -> untyped - - alias actions action - - def send_actions: (untyped data) -> untyped - - def release_actions: () -> untyped - - def print_page: (?::Hash[untyped, untyped] options) -> untyped - - def click_element: (untyped element) -> untyped - - def send_keys_to_element: (untyped element, untyped keys) -> untyped - - def upload: (untyped local_file) -> untyped - - def clear_element: (untyped element) -> untyped - - def submit_element: (untyped element) -> untyped - - def element_tag_name: (untyped element) -> untyped - - def element_attribute: (untyped element, untyped name) -> untyped - - def element_dom_attribute: (untyped element, untyped name) -> untyped - - def element_property: (untyped element, untyped name) -> untyped - - def element_aria_role: (untyped element) -> untyped - - def element_aria_label: (untyped element) -> untyped - - def element_value: (untyped element) -> untyped - - def element_text: (untyped element) -> untyped - - def element_location: (untyped element) -> untyped - - def element_rect: (untyped element) -> untyped - - def element_location_once_scrolled_into_view: (untyped element) -> untyped - - def element_size: (untyped element) -> untyped - - def element_enabled?: (untyped element) -> untyped - - def element_selected?: (untyped element) -> untyped - - def element_displayed?: (untyped element) -> untyped - - def element_value_of_css_property: (untyped element, untyped prop) -> untyped - - def active_element: () -> untyped - - alias switch_to_active_element active_element - - def find_element_by: (untyped how, untyped what, ?untyped parent_ref) -> untyped - - def find_elements_by: (untyped how, untyped what, ?untyped parent_ref) -> untyped - - def shadow_root: (untyped element) -> untyped - - def add_virtual_authenticator: (untyped options) -> untyped - - def remove_virtual_authenticator: (untyped id) -> untyped - - def add_credential: (untyped credential, untyped id) -> untyped - - def credentials: (untyped authenticator_id) -> untyped - - def remove_credential: (untyped credential_id, untyped authenticator_id) -> untyped - - def remove_all_credentials: (untyped authenticator_id) -> untyped - - def user_verified: (untyped verified, untyped authenticator_id) -> untyped - - private - - def execute: (untyped command, ?::Hash[untyped, untyped] opts, ?untyped? command_hash) -> String - - def escaper: () -> untyped - - def commands: (untyped command) -> untyped - - def unwrap_script_result: (untyped arg) -> untyped - - def element_id_from: (untyped id) -> untyped - - def shadow_root_id_from: (untyped id) -> untyped - - def prepare_capabilities_payload: (untyped capabilities) -> { capabilities: untyped } - - def convert_locator: (untyped how, untyped what) -> ::Array[untyped] - - ESCAPE_CSS_REGEXP: ::Regexp - - UNICODE_CODE_POINT: 30 - - def escape_css: (untyped string) -> untyped - end - end - end + def reset_fedcm_cooldown: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/remote/capabilities.rbs b/rb/sig/lib/selenium/webdriver/remote/capabilities.rbs index d562c1ee76dc1..064252edfb95e 100644 --- a/rb/sig/lib/selenium/webdriver/remote/capabilities.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/capabilities.rbs @@ -1,71 +1,26 @@ -module Selenium - module WebDriver - module Remote - class Capabilities - @capabilities: untyped +class Selenium::WebDriver::Remote::Capabilities + def self.json_create: (Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Capabilities - KNOWN: Array[Symbol] + def initialize: (?Hash[untyped, untyped]) -> void - def self.always_match: (untyped capabilities) -> untyped + def self.process_timeouts: (Selenium::WebDriver::Remote::Capabilities, Hash[untyped, untyped]) -> void - def self.first_match: (*untyped capabilities) -> untyped + def implicit_timeout=: (Integer) -> void - def self.json_create: (untyped data) -> untyped + def timeouts: () -> Hash[untyped, untyped] - def self.camel_case: (untyped str_or_sym) -> untyped + def page_load_timeout=: (Integer) -> void - private + def script_timeout=: (Integer) -> Integer - def self.process_timeouts: (untyped caps, untyped timeouts) -> untyped? + def self.camel_case: (Symbol) -> String - public + def []=: (Symbol, String) -> String + | (Symbol, bool) -> bool - def initialize: (?::Hash[untyped, untyped] opts) -> void + def merge!: (Hash[untyped, untyped]) -> void - def []=: (untyped key, untyped value) -> untyped + def []: (Symbol) -> String - def []: (untyped key) -> untyped - - def merge!: (untyped other) -> untyped - - def proxy: () -> untyped - - def proxy=: (untyped proxy) -> untyped - - def timeouts: () -> untyped - - def timeouts=: (untyped timeouts) -> untyped - - def implicit_timeout: () -> untyped - - def implicit_timeout=: (untyped timeout) -> untyped - - def page_load_timeout: () -> untyped - - def page_load_timeout=: (untyped timeout) -> untyped - - def script_timeout: () -> untyped - - def script_timeout=: (untyped timeout) -> untyped - - def as_json: (*untyped) -> untyped - - def to_json: (*untyped) -> untyped - - def ==: (untyped other) -> (bool | untyped) - - alias eql? == - - attr_reader capabilities: untyped - - private - - def process_capabilities: (untyped key, untyped value, untyped hash) -> untyped - - def convert_key: (untyped key) -> untyped - - def convert_value: (untyped key, untyped value) -> untyped - end - end - end + def browser_name: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/remote/http/common.rbs b/rb/sig/lib/selenium/webdriver/remote/http/common.rbs index dfafbbf8456bf..904664cb1f1fa 100644 --- a/rb/sig/lib/selenium/webdriver/remote/http/common.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/http/common.rbs @@ -1,41 +1,15 @@ -module Selenium - module WebDriver - module Remote - module Http - class Common - MAX_REDIRECTS: Integer +class Selenium::WebDriver::Remote::Http::Common + def call: (Symbol, String, Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Response + | (Symbol, String, nil) -> nil + | (Symbol, String, Hash[untyped, untyped]) -> nil + | (Symbol, String, nil) -> Selenium::WebDriver::Remote::Response - CONTENT_TYPE: String + def server_url: () -> URI::HTTP - DEFAULT_HEADERS: Hash[String, untyped] + def common_headers: () -> Hash[untyped, untyped] - @common_headers: Hash[String, untyped] + def create_response: (String, String, String) -> Selenium::WebDriver::Remote::Response + | (String, String, String) -> nil - attr_accessor self.extra_headers: Hash[String, untyped] - - attr_writer self.user_agent: String - - def self.user_agent: -> String - - attr_writer server_url: String - - def quit_errors: () -> Array[untyped] - - def close: () -> nil - - def call: (untyped verb, untyped url, untyped command_hash) -> untyped - - private - - def common_headers: -> Hash[String, untyped] - - def server_url: () -> String - - def request: (*untyped) -> untyped - - def create_response: (Integer code, Hash[String, untyped] body, String content_type) -> Remote::Response - end - end - end - end + def self.user_agent: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/remote/http/default.rbs b/rb/sig/lib/selenium/webdriver/remote/http/default.rbs index 7fb7a41c9ac7a..6815080b220ff 100644 --- a/rb/sig/lib/selenium/webdriver/remote/http/default.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/http/default.rbs @@ -1,48 +1,31 @@ -module Selenium - module WebDriver - module Remote - module Http - # @api private - class Default < Common - @open_timeout: untyped +class Selenium::WebDriver::Remote::Http::Default + def request: (Symbol, URI::HTTP, Hash[untyped, untyped], String, ?Integer) -> Selenium::WebDriver::Remote::Response + | (Symbol, URI::HTTP, Hash[untyped, untyped], nil, ?Integer) -> nil + | (Symbol, URI::HTTP, Hash[untyped, untyped], String, ?Integer) -> nil + | (Symbol, URI::HTTP, Hash[untyped, untyped], nil, ?Integer) -> Selenium::WebDriver::Remote::Response - @read_timeout: untyped + def new_request_for: (Symbol, URI::HTTP, Hash[untyped, untyped], String) -> Net::HTTP::Post + | (Symbol, URI::HTTP, Hash[untyped, untyped], nil) -> Net::HTTP::Get + | (Symbol, URI::HTTP, Hash[untyped, untyped], nil) -> Net::HTTP::Delete - @http: untyped + def response_for: (Net::HTTP::Post) -> Net::HTTPOK + | (Net::HTTP::Get) -> Net::HTTPNotFound + | (Net::HTTP::Post) -> Net::HTTPNotFound + | (Net::HTTP::Delete) -> Net::HTTPOK + | (Net::HTTP::Get) -> Net::HTTPOK + | (Net::HTTP::Post) -> Net::HTTPInternalServerError - @proxy: untyped + def http: () -> Net::HTTP - attr_writer proxy: untyped + def close: () -> nil - attr_accessor open_timeout: untyped + def initialize: (?open_timeout: nil, ?read_timeout: nil) -> void - attr_accessor read_timeout: untyped + def new_http_client: () -> Net::HTTP - def initialize: (?open_timeout: untyped?, ?read_timeout: untyped?) -> void + def use_proxy?: () -> bool - def close: () -> untyped + def proxy: () -> nil - private - - def http: () -> untyped - - def start: (untyped http) -> untyped - - MAX_RETRIES: Integer - - def request: (untyped verb, untyped url, untyped headers, untyped payload, ?::Integer redirects) -> untyped - - def new_request_for: (untyped verb, untyped url, untyped headers, untyped payload) -> untyped - - def response_for: (untyped request) -> untyped - - def new_http_client: () -> untyped - - def proxy: () -> untyped - - def use_proxy?: () -> untyped - end - end - end - end + def start: (Net::HTTP) -> void end diff --git a/rb/sig/lib/selenium/webdriver/remote/response.rbs b/rb/sig/lib/selenium/webdriver/remote/response.rbs index 3afa65955917b..fd939bf98af48 100644 --- a/rb/sig/lib/selenium/webdriver/remote/response.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/response.rbs @@ -1,31 +1,20 @@ -module Selenium - module WebDriver - module Remote - class Response - @code: Integer +class Selenium::WebDriver::Remote::Response + def initialize: (Integer, ?Hash[untyped, untyped]) -> void - @payload: Hash[untyped, untyped] + def assert_ok: () -> nil - attr_reader code: Integer + def error: () -> nil + | () -> Selenium::WebDriver::Error::NoSuchAlertError + | () -> Selenium::WebDriver::Error::UnknownError - attr_reader payload: Hash[untyped, untyped] + def process_error: () -> nil + | () -> Array[untyped] - def initialize: (Integer code, ?Hash[untyped, untyped]? payload) -> void + def []: (String) -> nil + | (String) -> Hash[untyped, untyped] + | (String) -> String + | (String) -> Array[untyped] - def error: () -> Error::WebDriverError? - - def []: (untyped key) -> untyped - - private - - def assert_ok: () -> Error::WebDriverError - - def add_cause: (Error::WebDriverError ex, String error, Array[String] backtrace) -> Error::WebDriverError - - def backtrace_from_remote: -> Array[String] - - def process_error: () -> Array[Hash[untyped, untyped]] - end - end - end + def add_cause: (Selenium::WebDriver::Error::NoSuchAlertError, String, String) -> void + | (Selenium::WebDriver::Error::UnknownError, String, String) -> void end diff --git a/rb/sig/lib/selenium/webdriver/support/guards.rbs b/rb/sig/lib/selenium/webdriver/support/guards.rbs index 2f7c90896426d..f85487134107b 100644 --- a/rb/sig/lib/selenium/webdriver/support/guards.rbs +++ b/rb/sig/lib/selenium/webdriver/support/guards.rbs @@ -1,41 +1,19 @@ -module Selenium - module WebDriver - module Support - class Guards - @example: untyped +class Selenium::WebDriver::Support::Guards + def initialize: (RSpec::Core::Example, ?bug_tracker: String, ?conditions: nil) -> void - @bug_tracker: untyped + def collect_example_guards: () -> Array[untyped] - @guard_conditions: untyped + def add_condition: (Symbol, ?Symbol) -> void + | (Symbol, ?nil) -> void + | (Symbol, ?bool) -> void - @guards: untyped + def disposition: () -> nil + | () -> Array[untyped] - @messages: untyped + def skipping_guard: () -> nil - GUARD_TYPES: Array[Symbol] + def satisfied?: (Selenium::WebDriver::Support::Guards::Guard) -> bool - attr_reader messages: untyped - - attr_accessor bug_tracker: untyped - - def initialize: (untyped example, ?bug_tracker: String, ?conditions: untyped?) -> void - - def add_condition: (untyped name, ?untyped? condition) { () -> untyped } -> untyped - - def add_message: (untyped name, untyped message) -> untyped - - def disposition: () -> Array[untyped]? - - def satisfied?: (untyped guard) -> untyped - - private - - def collect_example_guards: () -> untyped - - def skipping_guard: () -> untyped - - def pending_guard: () -> untyped - end - end - end + def pending_guard: () -> nil + | () -> Selenium::WebDriver::Support::Guards::Guard end diff --git a/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs b/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs index 70c13b3cb0312..6e12128ca083a 100644 --- a/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs +++ b/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs @@ -1,40 +1,13 @@ -module Selenium - module WebDriver - module Support - class Guards - class Guard - @guarded: untyped +class Selenium::WebDriver::Support::Guards::Guard + def initialize: (Hash[untyped, untyped], Symbol, ?Selenium::WebDriver::Support::Guards) -> void - @tracker: untyped + def exclusive?: () -> bool - @messages: untyped + def exclude?: () -> bool - @type: untyped + def except?: () -> bool - @reason: untyped + def only?: () -> bool - attr_reader guarded: untyped - - attr_reader tracker: String - attr_reader type: untyped - - attr_reader messages: untyped - - attr_reader reason: untyped - - def initialize: (untyped guarded, untyped type, ?untyped? guards) -> void - - def message: () -> untyped - - def except?: () -> untyped - - def only?: () -> untyped - - def exclude?: () -> untyped - - def exclusive?: () -> untyped - end - end - end - end + def message: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/support/guards/guard_condition.rbs b/rb/sig/lib/selenium/webdriver/support/guards/guard_condition.rbs index f7f0d50690a24..2f6ac4c28da01 100644 --- a/rb/sig/lib/selenium/webdriver/support/guards/guard_condition.rbs +++ b/rb/sig/lib/selenium/webdriver/support/guards/guard_condition.rbs @@ -1,21 +1,6 @@ -module Selenium - module WebDriver - module Support - class Guards - class GuardCondition - @name: untyped +class Selenium::WebDriver::Support::Guards::GuardCondition + def initialize: (Symbol, ?Symbol) -> void + | (Symbol, ?bool) -> void - @execution: untyped - - attr_accessor name: untyped - - attr_accessor execution: untyped - - def initialize: (untyped name, ?untyped? condition) ?{ () -> untyped } -> void - - def satisfied?: (untyped guard) -> untyped - end - end - end - end + def satisfied?: (Selenium::WebDriver::Support::Guards::Guard) -> bool end diff --git a/rb/spec/integration/selenium/webdriver/spec_helper.rb b/rb/spec/integration/selenium/webdriver/spec_helper.rb index dace160154833..3f564ef270931 100644 --- a/rb/spec/integration/selenium/webdriver/spec_helper.rb +++ b/rb/spec/integration/selenium/webdriver/spec_helper.rb @@ -64,6 +64,7 @@ def example_finished(notification) GlobalTestEnv.quit_driver trace.disable trace.save_comments + trace.save_files(out_dir: 'sig/') end c.filter_run_when_matching :focus From 5fe85cd2b996186cf55f5489c14000b943998352 Mon Sep 17 00:00:00 2001 From: aguspe Date: Fri, 2 May 2025 22:34:35 +0200 Subject: [PATCH 4/6] change platforms for rbs trace --- rb/Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rb/Gemfile b/rb/Gemfile index 9ea2d48cec7b6..9c891677f09d0 100644 --- a/rb/Gemfile +++ b/rb/Gemfile @@ -11,4 +11,4 @@ gem 'curb', '~> 1.0.5', require: false, platforms: %i[mri mingw x64_mingw] gem 'debug', '~> 1.7', require: false, platforms: %i[mri mingw x64_mingw] gem 'steep', '~> 1.5.0', require: false, platforms: %i[mri mingw x64_mingw] -gem "rbs-trace", "~> 0.5.1" +gem 'rbs-trace', '~> 0.5.1', require: false, platforms: %i[mri mingw x64_mingw] From 481434f46aa8e2c2373d8d22c8bfd5d7389b0151 Mon Sep 17 00:00:00 2001 From: aguspe Date: Mon, 5 May 2025 21:42:10 +0200 Subject: [PATCH 5/6] Fix trace load issue --- .../selenium/webdriver/chromium/features.rbs | 43 ++--------------- .../webdriver/common/child_process.rbs | 8 ---- .../lib/selenium/webdriver/common/driver.rbs | 16 ------- .../has_network_conditions.rbs | 14 ++---- .../lib/selenium/webdriver/common/error.rbs | 7 --- .../selenium/webdriver/common/platform.rbs | 26 ----------- .../webdriver/common/service_manager.rbs | 18 -------- .../lib/selenium/webdriver/remote/bridge.rbs | 46 +------------------ .../selenium/webdriver/remote/http/common.rbs | 5 -- .../webdriver/remote/http/default.rbs | 17 +------ .../selenium/webdriver/remote/response.rbs | 7 --- .../lib/selenium/webdriver/support/guards.rbs | 2 - .../webdriver/support/guards/guard.rbs | 2 - .../selenium/webdriver/spec_helper.rb | 30 ++++++++---- 14 files changed, 30 insertions(+), 211 deletions(-) diff --git a/rb/sig/lib/selenium/webdriver/chromium/features.rbs b/rb/sig/lib/selenium/webdriver/chromium/features.rbs index a48cca64401fe..6138564cf539d 100644 --- a/rb/sig/lib/selenium/webdriver/chromium/features.rbs +++ b/rb/sig/lib/selenium/webdriver/chromium/features.rbs @@ -1,42 +1,5 @@ -module Selenium - module WebDriver - module Chromium - module Features - include _Bridge +module Selenium::WebDriver::Chromium::Features + def network_conditions=: (Hash[untyped, untyped]) -> nil - CHROMIUM_COMMANDS: Hash[Symbol, Array[Symbol | String]] - - def commands: (Symbol command) -> Array[Symbol | String] - - def launch_app: (String id) -> String - - def cast_sinks: () -> Array[String] - - def cast_sink_to_use=: (String name) -> untyped - - def cast_issue_message: () -> String - - def start_cast_tab_mirroring: (String name) -> untyped - - def start_cast_desktop_mirroring: (String name) -> untyped - - def stop_casting: (String name) -> untyped - - def set_permission: (String name, String value) -> untyped - - def network_conditions: () -> Hash[untyped, untyped] - - def network_conditions=: (Hash[Symbol | String, Integer | bool] conditions) -> untyped - - def delete_network_conditions: () -> untyped - - def send_command: (Hash[String | Symbol, untyped] command_params) -> untyped - - def available_log_types: () -> Array[Symbol] - - def log: (Symbol type) -> Array[Hash[String, untyped]] | - (Symbol type) -> Array[LogEntry] - end - end - end + def network_conditions: () -> Hash[untyped, untyped] end diff --git a/rb/sig/lib/selenium/webdriver/common/child_process.rbs b/rb/sig/lib/selenium/webdriver/common/child_process.rbs index 930dcf380b69b..93dd1e889e760 100644 --- a/rb/sig/lib/selenium/webdriver/common/child_process.rbs +++ b/rb/sig/lib/selenium/webdriver/common/child_process.rbs @@ -5,12 +5,4 @@ class Selenium::WebDriver::ChildProcess | (Integer, ?Integer) -> Array[untyped] def poll_for_exit: (Integer) -> nil - - def self.build: (*String) -> Selenium::WebDriver::ChildProcess - - def initialize: (*String) -> void - - def start: () -> nil - - def io: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/common/driver.rbs b/rb/sig/lib/selenium/webdriver/common/driver.rbs index f483ba344a8ce..add61da7f2113 100644 --- a/rb/sig/lib/selenium/webdriver/common/driver.rbs +++ b/rb/sig/lib/selenium/webdriver/common/driver.rbs @@ -1,19 +1,3 @@ class Selenium::WebDriver::Driver - def get: (String) -> nil - - def navigate: () -> Selenium::WebDriver::Navigation - def quit: () -> nil - - def self.for: (Symbol, ?Hash[untyped, untyped]) -> Selenium::WebDriver::Chrome::Driver - - def service_url: (Selenium::WebDriver::Chrome::Service) -> URI::HTTP - - def initialize: (?bridge: nil, ?listener: nil, **Hash[untyped, untyped] | URI::HTTP) -> void - - def create_bridge: (caps: Hash[untyped, untyped], url: URI::HTTP, ?http_client: nil) -> Selenium::WebDriver::Remote::Bridge - - def add_extensions: (Symbol) -> Array[untyped] - - def execute_script: (String, *nil) -> void end diff --git a/rb/sig/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rbs b/rb/sig/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rbs index bd77ff746b2f4..f440dd9bb9408 100644 --- a/rb/sig/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rbs +++ b/rb/sig/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rbs @@ -1,13 +1,5 @@ -module Selenium - module WebDriver - module DriverExtensions - module HasNetworkConditions - def network_conditions: () -> untyped +module Selenium::WebDriver::DriverExtensions::HasNetworkConditions + def network_conditions=: (Hash[untyped, untyped]) -> void - def network_conditions=: (untyped conditions) -> untyped - - def delete_network_conditions: () -> untyped - end - end - end + def network_conditions: () -> Hash[untyped, untyped] end diff --git a/rb/sig/lib/selenium/webdriver/common/error.rbs b/rb/sig/lib/selenium/webdriver/common/error.rbs index b2bbcdbd4e9dc..76eca218404a6 100644 --- a/rb/sig/lib/selenium/webdriver/common/error.rbs +++ b/rb/sig/lib/selenium/webdriver/common/error.rbs @@ -1,10 +1,3 @@ module Selenium::WebDriver::Error def self.for_error: (nil) -> nil - | (String) -> Class -end - -class Selenium::WebDriver::Error::WebDriverError - def initialize: (?String) -> void - - def class_name: () -> Symbol end diff --git a/rb/sig/lib/selenium/webdriver/common/platform.rbs b/rb/sig/lib/selenium/webdriver/common/platform.rbs index eee33169de034..5d49d3a16b2ff 100644 --- a/rb/sig/lib/selenium/webdriver/common/platform.rbs +++ b/rb/sig/lib/selenium/webdriver/common/platform.rbs @@ -2,30 +2,4 @@ module Selenium::WebDriver::Platform def self.ci: () -> nil def self.os: () -> Symbol - - def self.localhost: () -> String - - def self.jruby?: () -> bool - - def self.engine: () -> Symbol - - def self.windows?: () -> bool - - def self.truffleruby?: () -> bool - - def self.cygwin_path: (String, ?only_cygwin: bool, **nil) -> String - - def self.cygwin?: () -> bool - - def self.assert_executable: (String) -> void - - def self.assert_file: (String) -> void - - def self.exit_hook: () -> void - - def self.interfaces: () -> Array[untyped] - - def self.ip: () -> String - - def self.null_device: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/common/service_manager.rbs b/rb/sig/lib/selenium/webdriver/common/service_manager.rbs index 692eea398884a..e0474f27e3ef9 100644 --- a/rb/sig/lib/selenium/webdriver/common/service_manager.rbs +++ b/rb/sig/lib/selenium/webdriver/common/service_manager.rbs @@ -8,22 +8,4 @@ class Selenium::WebDriver::ServiceManager def connect_to_server: () -> Net::HTTPOK def stop_process: () -> nil - - def initialize: (Selenium::WebDriver::Chrome::Service) -> void - - def start: () -> void - - def process_running?: () -> nil - - def socket_lock: () -> Selenium::WebDriver::SocketLock - - def find_free_port: () -> void - - def start_process: () -> void - - def build_process: (*String) -> Selenium::WebDriver::ChildProcess - - def connect_until_stable: () -> nil - - def uri: () -> URI::HTTP end diff --git a/rb/sig/lib/selenium/webdriver/remote/bridge.rbs b/rb/sig/lib/selenium/webdriver/remote/bridge.rbs index 4922ab6b89821..32f72a8814ec4 100644 --- a/rb/sig/lib/selenium/webdriver/remote/bridge.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/bridge.rbs @@ -1,53 +1,9 @@ class Selenium::WebDriver::Remote::Bridge - def get: (String) -> nil - def execute: (Symbol, ?Hash[untyped, untyped], ?Hash[untyped, untyped]) -> nil - | (Symbol, ?Hash[untyped, untyped], ?nil) -> nil - | (Symbol, ?Hash[untyped, untyped], ?Hash[untyped, untyped]) -> Hash[untyped, untyped] - | (Symbol, ?Hash[untyped, untyped], ?nil) -> String | (Symbol, ?Hash[untyped, untyped], ?nil) -> Hash[untyped, untyped] - | (Symbol, ?Hash[untyped, untyped], ?nil) -> Array[untyped] + | (Symbol, ?Hash[untyped, untyped], ?nil) -> nil def session_id: () -> String - def fedcm_title: () -> nil - | () -> String - - def fedcm_subtitle: () -> nil - - def fedcm_dialog_type: () -> nil - | () -> String - - def fedcm_account_list: () -> nil - | () -> Array[untyped] - - def select_fedcm_account: (Integer) -> nil - - def cancel_fedcm_dialog: () -> nil - def quit: () -> nil - - def initialize: (url: URI::HTTP, ?http_client: nil) -> void - - def self.locator_converter: () -> Selenium::WebDriver::Remote::Bridge::LocatorConverter - - def create_session: (Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Bridge - - def prepare_capabilities_payload: (Hash[untyped, untyped]) -> Hash[untyped, untyped] - - def commands: (Symbol) -> Array[untyped] - - def command_list: () -> Hash[untyped, untyped] - - def browser: () -> Symbol - - def execute_script: (String, *nil) -> nil - - def unwrap_script_result: (nil) -> nil - - def click_fedcm_dialog_button: () -> nil - - def fedcm_delay: (bool) -> nil - - def reset_fedcm_cooldown: () -> nil end diff --git a/rb/sig/lib/selenium/webdriver/remote/http/common.rbs b/rb/sig/lib/selenium/webdriver/remote/http/common.rbs index 904664cb1f1fa..b4408d9f4f6e3 100644 --- a/rb/sig/lib/selenium/webdriver/remote/http/common.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/http/common.rbs @@ -1,7 +1,5 @@ class Selenium::WebDriver::Remote::Http::Common def call: (Symbol, String, Hash[untyped, untyped]) -> Selenium::WebDriver::Remote::Response - | (Symbol, String, nil) -> nil - | (Symbol, String, Hash[untyped, untyped]) -> nil | (Symbol, String, nil) -> Selenium::WebDriver::Remote::Response def server_url: () -> URI::HTTP @@ -9,7 +7,4 @@ class Selenium::WebDriver::Remote::Http::Common def common_headers: () -> Hash[untyped, untyped] def create_response: (String, String, String) -> Selenium::WebDriver::Remote::Response - | (String, String, String) -> nil - - def self.user_agent: () -> String end diff --git a/rb/sig/lib/selenium/webdriver/remote/http/default.rbs b/rb/sig/lib/selenium/webdriver/remote/http/default.rbs index 6815080b220ff..91860b808ee63 100644 --- a/rb/sig/lib/selenium/webdriver/remote/http/default.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/http/default.rbs @@ -1,7 +1,5 @@ class Selenium::WebDriver::Remote::Http::Default def request: (Symbol, URI::HTTP, Hash[untyped, untyped], String, ?Integer) -> Selenium::WebDriver::Remote::Response - | (Symbol, URI::HTTP, Hash[untyped, untyped], nil, ?Integer) -> nil - | (Symbol, URI::HTTP, Hash[untyped, untyped], String, ?Integer) -> nil | (Symbol, URI::HTTP, Hash[untyped, untyped], nil, ?Integer) -> Selenium::WebDriver::Remote::Response def new_request_for: (Symbol, URI::HTTP, Hash[untyped, untyped], String) -> Net::HTTP::Post @@ -9,23 +7,10 @@ class Selenium::WebDriver::Remote::Http::Default | (Symbol, URI::HTTP, Hash[untyped, untyped], nil) -> Net::HTTP::Delete def response_for: (Net::HTTP::Post) -> Net::HTTPOK - | (Net::HTTP::Get) -> Net::HTTPNotFound - | (Net::HTTP::Post) -> Net::HTTPNotFound - | (Net::HTTP::Delete) -> Net::HTTPOK | (Net::HTTP::Get) -> Net::HTTPOK - | (Net::HTTP::Post) -> Net::HTTPInternalServerError + | (Net::HTTP::Delete) -> Net::HTTPOK def http: () -> Net::HTTP def close: () -> nil - - def initialize: (?open_timeout: nil, ?read_timeout: nil) -> void - - def new_http_client: () -> Net::HTTP - - def use_proxy?: () -> bool - - def proxy: () -> nil - - def start: (Net::HTTP) -> void end diff --git a/rb/sig/lib/selenium/webdriver/remote/response.rbs b/rb/sig/lib/selenium/webdriver/remote/response.rbs index fd939bf98af48..64709fbaf04c5 100644 --- a/rb/sig/lib/selenium/webdriver/remote/response.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/response.rbs @@ -4,17 +4,10 @@ class Selenium::WebDriver::Remote::Response def assert_ok: () -> nil def error: () -> nil - | () -> Selenium::WebDriver::Error::NoSuchAlertError - | () -> Selenium::WebDriver::Error::UnknownError def process_error: () -> nil | () -> Array[untyped] def []: (String) -> nil | (String) -> Hash[untyped, untyped] - | (String) -> String - | (String) -> Array[untyped] - - def add_cause: (Selenium::WebDriver::Error::NoSuchAlertError, String, String) -> void - | (Selenium::WebDriver::Error::UnknownError, String, String) -> void end diff --git a/rb/sig/lib/selenium/webdriver/support/guards.rbs b/rb/sig/lib/selenium/webdriver/support/guards.rbs index f85487134107b..bc593602f7790 100644 --- a/rb/sig/lib/selenium/webdriver/support/guards.rbs +++ b/rb/sig/lib/selenium/webdriver/support/guards.rbs @@ -8,12 +8,10 @@ class Selenium::WebDriver::Support::Guards | (Symbol, ?bool) -> void def disposition: () -> nil - | () -> Array[untyped] def skipping_guard: () -> nil def satisfied?: (Selenium::WebDriver::Support::Guards::Guard) -> bool def pending_guard: () -> nil - | () -> Selenium::WebDriver::Support::Guards::Guard end diff --git a/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs b/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs index 6e12128ca083a..5791eb1c39ee4 100644 --- a/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs +++ b/rb/sig/lib/selenium/webdriver/support/guards/guard.rbs @@ -8,6 +8,4 @@ class Selenium::WebDriver::Support::Guards::Guard def except?: () -> bool def only?: () -> bool - - def message: () -> String end diff --git a/rb/spec/integration/selenium/webdriver/spec_helper.rb b/rb/spec/integration/selenium/webdriver/spec_helper.rb index 3f564ef270931..e51fdb6c1631b 100644 --- a/rb/spec/integration/selenium/webdriver/spec_helper.rb +++ b/rb/spec/integration/selenium/webdriver/spec_helper.rb @@ -19,7 +19,6 @@ require 'rubygems' require 'time' -require 'rbs-trace' require 'rspec' require 'selenium-webdriver' @@ -36,13 +35,28 @@ def example_finished(notification) exception = notification.example.exception assertion_failed = exception && (exception.is_a?(RSpec::Expectations::ExpectationNotMetError) || - exception.is_a?(RSpec::Core::Pending::PendingExampleFixedError)) + exception.is_a?(RSpec::Core::Pending::PendingExampleFixedError)) pending_exception = exception.nil? && notification.example.pending && !notification.example.skip GlobalTestEnv.reset_driver! if (exception && !assertion_failed) || pending_exception end end +module TraceHelper + # @rbs () -> RBS::Trace + def self.trace + @trace ||= if Gem::Specification.find_all_by_name('rbs-trace').any? + require 'rbs-trace' + RBS::Trace.new + end + end + + # @rbs () -> bool + def self.enabled? + !trace.nil? + end +end + RSpec.configure do |c| c.define_derived_metadata do |meta| meta[:aggregate_failures] = true @@ -52,19 +66,19 @@ def example_finished(notification) c.include(WebDriver::SpecSupport::Helpers) - trace = RBS::Trace.new - c.before(:suite) do GlobalTestEnv.remote_server.start if GlobalTestEnv.driver == :remote && ENV['WD_REMOTE_URL'].nil? GlobalTestEnv.print_env - trace.enable + TraceHelper.trace.enable if TraceHelper.enabled? end c.after(:suite) do GlobalTestEnv.quit_driver - trace.disable - trace.save_comments - trace.save_files(out_dir: 'sig/') + if TraceHelper.enabled? + TraceHelper.trace.disable + TraceHelper.trace.save_comments + TraceHelper.trace.save_files(out_dir: 'sig/') + end end c.filter_run_when_matching :focus From 68c1e73181cfc50688dd5e35c2d79eab249ab7ef Mon Sep 17 00:00:00 2001 From: aguspe Date: Mon, 5 May 2025 22:41:40 +0200 Subject: [PATCH 6/6] remove trace from CI --- rb/spec/integration/selenium/webdriver/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rb/spec/integration/selenium/webdriver/spec_helper.rb b/rb/spec/integration/selenium/webdriver/spec_helper.rb index e51fdb6c1631b..ecf88acd9570e 100644 --- a/rb/spec/integration/selenium/webdriver/spec_helper.rb +++ b/rb/spec/integration/selenium/webdriver/spec_helper.rb @@ -45,7 +45,7 @@ def example_finished(notification) module TraceHelper # @rbs () -> RBS::Trace def self.trace - @trace ||= if Gem::Specification.find_all_by_name('rbs-trace').any? + @trace ||= if GlobalTestEnv.send(:current_env)[:ci].nil? require 'rbs-trace' RBS::Trace.new end