[rb] create user-friendly method for enabling bidi (#14284)

* Add support for bidi as an initialization parameter

* change which tests guard for bidi

---------

Co-authored-by: aguspe <[email protected]>
diff --git a/rb/lib/selenium/webdriver/common/options.rb b/rb/lib/selenium/webdriver/common/options.rb
index 997aced..4616a2c 100644
--- a/rb/lib/selenium/webdriver/common/options.rb
+++ b/rb/lib/selenium/webdriver/common/options.rb
@@ -71,6 +71,8 @@
       def initialize(**opts)
         self.class.set_capabilities
 
+        opts[:web_socket_url] = opts.delete(:bidi) if opts.key?(:bidi)
+
         @options = opts
         @options[:browser_name] = self.class::BROWSER
       end
@@ -91,6 +93,14 @@
         @options[name] = value
       end
 
+      def enable_bidi!
+        @options[:web_socket_url] = true
+      end
+
+      def bidi?
+        !!@options[:web_socket_url]
+      end
+
       def ==(other)
         return false unless other.is_a? self.class
 
diff --git a/rb/sig/lib/selenium/webdriver/common/options.rbs b/rb/sig/lib/selenium/webdriver/common/options.rbs
index d2fe0cc..b49c133 100644
--- a/rb/sig/lib/selenium/webdriver/common/options.rbs
+++ b/rb/sig/lib/selenium/webdriver/common/options.rbs
@@ -39,6 +39,10 @@
 
       def ==: (untyped other) -> bool
 
+      def bidi?: -> bool
+
+      def enable_bidi!: -> bool
+
       alias eql? ==
 
       def as_json: (*untyped) -> untyped
diff --git a/rb/spec/integration/selenium/webdriver/chrome/options_spec.rb b/rb/spec/integration/selenium/webdriver/chrome/options_spec.rb
index b1919c9..d687a50 100644
--- a/rb/spec/integration/selenium/webdriver/chrome/options_spec.rb
+++ b/rb/spec/integration/selenium/webdriver/chrome/options_spec.rb
@@ -22,7 +22,7 @@
 module Selenium
   module WebDriver
     module Chrome
-      describe Options, exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'}, {browser: :chrome}] do
+      describe Options, exclusive: {browser: :chrome} do
         it 'passes emulated device correctly' do
           reset_driver!(emulation: {device_name: 'Nexus 5'}) do |driver|
             ua = driver.execute_script 'return window.navigator.userAgent'
@@ -43,6 +43,39 @@
             expect(ua).to eq('foo;bar')
           end
         end
+
+        it 'enables bidi', exclusive: {bidi: true, reason: 'bazel does not have dependencies otherwise'} do
+          quit_driver
+
+          options = Selenium::WebDriver::Options.chrome
+          expect(options.web_socket_url).to be_nil
+          expect(options.bidi?).to be false
+
+          options.enable_bidi!
+          expect(options.web_socket_url).to be true
+          expect(options.bidi?).to be true
+
+          driver = Selenium::WebDriver.for :chrome, options: options
+
+          expect(driver.capabilities.web_socket_url).to be_a String
+
+          driver.quit
+        end
+
+        it 'enables BiDi on initialization',
+           exclusive: {bidi: true, reason: 'bazel does not have dependencies otherwise'} do
+          quit_driver
+
+          options = Selenium::WebDriver::Options.chrome(bidi: true)
+          expect(options.web_socket_url).to be true
+          expect(options.bidi?).to be true
+
+          driver = Selenium::WebDriver.for :chrome, options: options
+
+          expect(driver.capabilities.web_socket_url).to be_a String
+
+          driver.quit
+        end
       end
     end # Chrome
   end # WebDriver
diff --git a/rb/spec/integration/selenium/webdriver/edge/options_spec.rb b/rb/spec/integration/selenium/webdriver/edge/options_spec.rb
index a6c6cac..f5ec3c9 100644
--- a/rb/spec/integration/selenium/webdriver/edge/options_spec.rb
+++ b/rb/spec/integration/selenium/webdriver/edge/options_spec.rb
@@ -22,7 +22,7 @@
 module Selenium
   module WebDriver
     module Edge
-      describe Options, exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'}, {browser: :edge}] do
+      describe Options, exclusive: {browser: :edge} do
         it 'passes emulated device correctly' do
           reset_driver!(emulation: {device_name: 'Nexus 5'}) do |driver|
             ua = driver.execute_script 'return window.navigator.userAgent'
@@ -43,6 +43,39 @@
             expect(ua).to eq('foo;bar')
           end
         end
+
+        it 'enables bidi', exclusive: {bidi: true, reason: 'bazel does not have dependencies otherwise'} do
+          quit_driver
+
+          options = Selenium::WebDriver::Options.chrome
+          expect(options.web_socket_url).to be_nil
+          expect(options.bidi?).to be false
+
+          options.enable_bidi!
+          expect(options.web_socket_url).to be true
+          expect(options.bidi?).to be true
+
+          driver = Selenium::WebDriver.for :chrome, options: options
+
+          expect(driver.capabilities.web_socket_url).to be_a String
+
+          driver.quit
+        end
+
+        it 'enables BiDi on initialization',
+           exclusive: {bidi: true, reason: 'bazel does not have dependencies otherwise'} do
+          quit_driver
+
+          options = Selenium::WebDriver::Options.edge(bidi: true)
+          expect(options.web_socket_url).to be true
+          expect(options.bidi?).to be true
+
+          driver = Selenium::WebDriver.for :edge, options: options
+
+          expect(driver.capabilities.web_socket_url).to be_a String
+
+          driver.quit
+        end
       end
     end # Edge
   end # WebDriver
diff --git a/rb/spec/unit/selenium/webdriver/chrome/options_spec.rb b/rb/spec/unit/selenium/webdriver/chrome/options_spec.rb
index 96a739e..aee28ee 100644
--- a/rb/spec/unit/selenium/webdriver/chrome/options_spec.rb
+++ b/rb/spec/unit/selenium/webdriver/chrome/options_spec.rb
@@ -141,6 +141,18 @@
           end
         end
 
+        describe '#enable_bidi!' do
+          it 'allows setting and querying bidi' do
+            expect(options.web_socket_url).to be_nil
+            expect(options.bidi?).to be false
+
+            options.enable_bidi!
+
+            expect(options.bidi?).to be true
+            expect(options.web_socket_url).to be true
+          end
+        end
+
         describe '#add_extension' do
           it 'adds an extension' do
             allow(File).to receive(:file?).and_return(true)