From 545c98dc3304d4ecb98b308738ea1ac002bc53fd Mon Sep 17 00:00:00 2001 From: hoanle0126 Date: Mon, 26 Oct 2026 15:27:50 +0700 Subject: [PATCH 1/2] fix: support symbol webSocketUrl capability for BiDiBridge and guard nil bidi on close --- .../common/base/bidi_bridge.rb | 4 +-- lib/appium_lib_core/common/base/driver.rb | 8 +++++- .../appium_lib_core/common/base/driver.rbs | 2 ++ test/unit/driver_test.rb | 28 +++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/appium_lib_core/common/base/bidi_bridge.rb b/lib/appium_lib_core/common/base/bidi_bridge.rb index 566fe0cc..09291194 100644 --- a/lib/appium_lib_core/common/base/bidi_bridge.rb +++ b/lib/appium_lib_core/common/base/bidi_bridge.rb @@ -80,11 +80,11 @@ def refresh def quit super ensure - bidi.close + bidi&.close end def close - execute(:close_window).tap { |handles| bidi.close if handles.empty? } + execute(:close_window).tap { |handles| bidi&.close if handles.empty? } end # steep:ignore:end diff --git a/lib/appium_lib_core/common/base/driver.rb b/lib/appium_lib_core/common/base/driver.rb index 3f24b203..859b8acd 100644 --- a/lib/appium_lib_core/common/base/driver.rb +++ b/lib/appium_lib_core/common/base/driver.rb @@ -86,7 +86,7 @@ def create_bridge(**opts) raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty? - @has_bidi = capabilities && capabilities['webSocketUrl'] ? true : false + @has_bidi = bidi_enabled?(capabilities) bridge_clzz = @has_bidi ? ::Appium::Core::Base::BiDiBridge : ::Appium::Core::Base::Bridge # steep:ignore:start bridge = bridge_clzz.new(**bridge_opts) @@ -103,6 +103,12 @@ def create_bridge(**opts) bridge end + def bidi_enabled?(capabilities) + return false unless capabilities + + ['webSocketUrl', :webSocketUrl, 'web_socket_url', :web_socket_url].any? { |key| capabilities[key] } + end + public # Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path. diff --git a/sig/lib/appium_lib_core/common/base/driver.rbs b/sig/lib/appium_lib_core/common/base/driver.rbs index e43be2a9..9875ea1f 100644 --- a/sig/lib/appium_lib_core/common/base/driver.rbs +++ b/sig/lib/appium_lib_core/common/base/driver.rbs @@ -42,6 +42,8 @@ module Appium def create_bridge: (**untyped opts) -> untyped + def bidi_enabled?: (untyped capabilities) -> bool + public def update_sending_request_to: (protocol: untyped, host: untyped, port: untyped, path: untyped) -> (nil | untyped) diff --git a/test/unit/driver_test.rb b/test/unit/driver_test.rb index 44c397d2..ff19cdf5 100644 --- a/test/unit/driver_test.rb +++ b/test/unit/driver_test.rb @@ -836,6 +836,34 @@ def test_bidi_bridge mock_bidi.verify end + def test_bidi_bridge_with_symbol_key_and_without_server_websocket_url + response = { + value: { + sessionId: '1234567890', + capabilities: { + platformName: :android, + automationName: ENV['APPIUM_DRIVER'] || 'uiautomator2', + deviceName: 'Android Emulator' + } + } + }.to_json + + stub_request(:post, 'http://127.0.0.1:4723/session') + .to_return(headers: HEADER, status: 200, body: response) + + capabilities = Caps.android[:capabilities].merge(webSocketUrl: true) + core = ::Appium::Core.for capabilities: capabilities + driver = core.start_driver + + assert_equal Appium::Core::Base::BiDiBridge, driver.send(:bridge).class + assert_nil driver.bidi + + stub_request(:delete, 'http://127.0.0.1:4723/session/1234567890') + .to_return(headers: HEADER, status: 200, body: { value: nil }.to_json) + + driver.quit + end + def test_elements driver = android_mock_create_session From ac4023363a09023ee4e64d69d106df14926d15a1 Mon Sep 17 00:00:00 2001 From: Nacy Dev <140143646+hoanle0126@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:01:40 +0700 Subject: [PATCH 2/2] fix: inline webSocketUrl check and remove bidi_enabled? helper --- lib/appium_lib_core/common/base/driver.rb | 8 +------- sig/lib/appium_lib_core/common/base/driver.rbs | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/appium_lib_core/common/base/driver.rb b/lib/appium_lib_core/common/base/driver.rb index 859b8acd..ab452746 100644 --- a/lib/appium_lib_core/common/base/driver.rb +++ b/lib/appium_lib_core/common/base/driver.rb @@ -86,7 +86,7 @@ def create_bridge(**opts) raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty? - @has_bidi = bidi_enabled?(capabilities) + @has_bidi = capabilities && (capabilities['webSocketUrl'] || capabilities[:webSocketUrl]) ? true : false bridge_clzz = @has_bidi ? ::Appium::Core::Base::BiDiBridge : ::Appium::Core::Base::Bridge # steep:ignore:start bridge = bridge_clzz.new(**bridge_opts) @@ -103,12 +103,6 @@ def create_bridge(**opts) bridge end - def bidi_enabled?(capabilities) - return false unless capabilities - - ['webSocketUrl', :webSocketUrl, 'web_socket_url', :web_socket_url].any? { |key| capabilities[key] } - end - public # Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path. diff --git a/sig/lib/appium_lib_core/common/base/driver.rbs b/sig/lib/appium_lib_core/common/base/driver.rbs index 9875ea1f..e43be2a9 100644 --- a/sig/lib/appium_lib_core/common/base/driver.rbs +++ b/sig/lib/appium_lib_core/common/base/driver.rbs @@ -42,8 +42,6 @@ module Appium def create_bridge: (**untyped opts) -> untyped - def bidi_enabled?: (untyped capabilities) -> bool - public def update_sending_request_to: (protocol: untyped, host: untyped, port: untyped, path: untyped) -> (nil | untyped)