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 92be65e3ebbad3801e7791fdbf528c0e54dd82bd Mon Sep 17 00:00:00 2001 From: aguspe Date: Wed, 15 Oct 2025 19:21:34 +0200 Subject: [PATCH 2/6] Remove nil values for network requests --- rb/lib/selenium/webdriver/bidi/network.rb | 21 +-- .../selenium/webdriver/bidi/network_spec.rb | 123 ++++++++++++++++++ 2 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 rb/spec/unit/selenium/webdriver/bidi/network_spec.rb diff --git a/rb/lib/selenium/webdriver/bidi/network.rb b/rb/lib/selenium/webdriver/bidi/network.rb index 26f62f64a22dc..0042ac8578d1d 100644 --- a/rb/lib/selenium/webdriver/bidi/network.rb +++ b/rb/lib/selenium/webdriver/bidi/network.rb @@ -82,15 +82,16 @@ def cancel_auth(request_id) end def continue_request(**args) - @bidi.send_cmd( - 'network.continueRequest', + args = { request: args[:id], body: args[:body], cookies: args[:cookies], headers: args[:headers], method: args[:method], url: args[:url] - ) + }.compact + + @bidi.send_cmd('network.continueRequest', **args) end def fail_request(request_id) @@ -101,27 +102,29 @@ def fail_request(request_id) end def continue_response(**args) - @bidi.send_cmd( - 'network.continueResponse', + args = { request: args[:id], cookies: args[:cookies], credentials: args[:credentials], headers: args[:headers], reasonPhrase: args[:reason], statusCode: args[:status] - ) + }.compact + + @bidi.send_cmd('network.continueResponse', **args) end def provide_response(**args) - @bidi.send_cmd( - 'network.provideResponse', + args = { request: args[:id], body: args[:body], cookies: args[:cookies], headers: args[:headers], reasonPhrase: args[:reason], statusCode: args[:status] - ) + }.compact + + @bidi.send_cmd('network.provideResponse', **args) end def set_cache_behavior(behavior, *contexts) diff --git a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb new file mode 100644 index 0000000000000..4b466ea853dec --- /dev/null +++ b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +# Licensed to the Software Freedom Conservancy (SFC) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The SFC licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +require File.expand_path('../spec_helper', __dir__) +# Adjust the require path as necessary for your project structure +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network', __dir__) + +module Selenium + module WebDriver + class BiDi + describe Network do + let(:mock_bidi) { instance_double(BiDi, 'Bidi') } + let(:network) { described_class.new(mock_bidi) } + let(:request_id) { '12345-request-id' } + + before { allow(mock_bidi).to receive(:send_cmd).and_return({}) } + + describe '#continue_request' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) + + network.continue_request(id: request_id) + end + + it 'sends only provided optional args' do + expected_payload = { + request: request_id, + body: {type: 'string', value: 'new body'}, + method: 'POST' + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) + + network.continue_request( + id: request_id, + body: {type: 'string', value: 'new body'}, + cookies: nil, + headers: nil, + method: 'POST' + ) + end + end + + describe '#continue_response' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) + + network.continue_response(id: request_id) + end + + it 'sends only provided optional args' do + expected_headers = [{name: 'Auth', value: {type: 'string', value: 'Token'}}] + expected_payload = { + request: request_id, + headers: expected_headers, + statusCode: 202 + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) + + network.continue_response( + id: request_id, + cookies: nil, + credentials: nil, + headers: expected_headers, + reason: nil, + status: 202 + ) + end + end + + describe '#provide_response' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} + + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) + + network.provide_response(id: request_id) + end + + it 'sends only provided optional args' do + expected_payload = { + request: request_id, + body: {type: 'string', value: 'Hello'}, + reasonPhrase: 'OK-Custom' + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) + + network.provide_response( + id: request_id, + body: {type: 'string', value: 'Hello'}, + cookies: nil, + headers: nil, + reason: 'OK-Custom', + status: nil + ) + end + end + end + end + end +end From 72445fc8d272685be4e433b78297688cf09a1f2e Mon Sep 17 00:00:00 2001 From: aguspe Date: Thu, 16 Oct 2025 20:36:46 +0200 Subject: [PATCH 3/6] Update intercept request and response and improve headers and cookies --- .../webdriver/bidi/network/cookies.rb | 13 +- .../bidi/network/intercepted_request.rb | 16 +- .../bidi/network/intercepted_response.rb | 18 +- .../bidi/network/intercepted_request.rbs | 14 +- .../bidi/network/intercepted_response.rbs | 6 +- .../bidi/intercepted_request_spec.rb | 104 ++++++++++ .../bidi/intercepted_response_spec.rb | 194 ++++++++++++++++++ 7 files changed, 336 insertions(+), 29 deletions(-) create mode 100644 rb/spec/unit/selenium/webdriver/bidi/intercepted_request_spec.rb create mode 100644 rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb diff --git a/rb/lib/selenium/webdriver/bidi/network/cookies.rb b/rb/lib/selenium/webdriver/bidi/network/cookies.rb index 7cc5d7871ce23..027a658a59f77 100644 --- a/rb/lib/selenium/webdriver/bidi/network/cookies.rb +++ b/rb/lib/selenium/webdriver/bidi/network/cookies.rb @@ -21,16 +21,13 @@ module Selenium module WebDriver class BiDi class Cookies < Hash - def initialize(cookies = {}) - super() - merge!(cookies) - end - def as_json - self[:name] = self[:name].to_s - self[:value] = {type: 'string', value: self[:value].to_s} + map do |name, val| + self[:name] = name.to_s + self[:value] = {type: 'string', value: val.to_s} - [compact] + [compact] + end end end end # BiDi diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb index ad2ef94295092..b7d66e2fde94f 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb @@ -25,21 +25,23 @@ module WebDriver class BiDi class InterceptedRequest < InterceptedItem attr_accessor :method, :url - attr_reader :body + attr_reader :body, :headers, :cookies def initialize(network, request) super @method = nil @url = nil @body = nil + @headers = nil + @cookies = nil end def continue network.continue_request( id: id, body: body, - cookies: cookies.as_json, - headers: headers.as_json, + cookies: cookies&.as_json, + headers: headers&.as_json, method: method, url: url ) @@ -56,12 +58,12 @@ def body=(value) } end - def headers - @headers ||= Headers.new + def headers=(headers = {}) + @headers = Headers.new(headers) end - def cookies(cookies = {}) - @cookies ||= Cookies.new(cookies) + def cookies=(cookies = {}) + @cookies = Cookies.new(cookies) end end end # BiDi diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb index 08e4b9c84a715..9fed545a4e73e 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb @@ -26,20 +26,22 @@ module WebDriver class BiDi class InterceptedResponse < InterceptedItem attr_accessor :reason, :status - attr_reader :body + attr_reader :body, :headers, :cookies def initialize(network, request) super @reason = nil @status = nil @body = nil + @headers = nil + @cookies = nil end def continue network.continue_response( id: id, - cookies: cookies.as_json, - headers: headers.as_json, + cookies: cookies&.as_json, + headers: headers&.as_json, credentials: credentials.as_json, reason: reason, status: status @@ -49,8 +51,8 @@ def continue def provide_response network.provide_response( id: id, - cookies: cookies.as_json, - headers: headers.as_json, + cookies: cookies&.as_json, + headers: headers&.as_json, body: body, reason: reason, status: status @@ -61,11 +63,11 @@ def credentials(username: nil, password: nil) @credentials ||= Credentials.new(username: username, password: password) end - def headers - @headers ||= Headers.new + def headers=(*headers) + @headers = Headers.new(headers) end - def cookies(cookies = {}) + def cookies=(cookies = {}) @cookies ||= Cookies.new(cookies) end diff --git a/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_request.rbs b/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_request.rbs index 04cecb59457dc..ad226a1922efa 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_request.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_request.rbs @@ -2,15 +2,15 @@ module Selenium module WebDriver class BiDi class InterceptedRequest < InterceptedItem - @method: String + @method: String? - @url: String + @url: String? - @body: Hash[untyped, untyped] + @body: Hash[untyped, untyped]? - @headers: Hash[untyped, untyped] + @headers: Hash[untyped, untyped]? - @cookies: Hash[untyped, untyped] + @cookies: Hash[untyped, untyped]? attr_accessor method: String @@ -22,6 +22,8 @@ module Selenium def continue: () -> Hash[nil, nil] + def cookies=: -> Hash[nil, nil] + def fail: () -> Hash[nil, nil] def body=: (Hash[untyped, untyped] value) -> Hash[untyped, untyped] @@ -29,6 +31,8 @@ module Selenium def headers: () -> Hash[untyped, untyped] def cookies: () -> Hash[untyped, untyped] + + def headers=: -> Hash[untyped, untyped] end end end diff --git a/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_response.rbs b/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_response.rbs index 22263c22165b3..f087452867b7b 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_response.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/network/intercepted_response.rbs @@ -5,7 +5,7 @@ module Selenium @body: untyped @cookies: Hash[Symbol, String | Integer]? - @reason: String + @reason: String? @credentials: untyped @@ -24,10 +24,14 @@ module Selenium def cookies:(?Hash[Symbol, String | Integer]? set_cookie_headers) -> untyped + def cookies=: -> Hash[Symbol, String | Integer] + def credentials: (?username: untyped?, ?password: untyped?) -> untyped def headers: () -> untyped + def headers=: -> Hash[untyped, untyped] + def provide_response: -> untyped def set_cookie_headers: (?untyped? set_cookie_headers) -> untyped diff --git a/rb/spec/unit/selenium/webdriver/bidi/intercepted_request_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/intercepted_request_spec.rb new file mode 100644 index 0000000000000..961e7dc3b8256 --- /dev/null +++ b/rb/spec/unit/selenium/webdriver/bidi/intercepted_request_spec.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +# Licensed to the Software Freedom Conservancy (SFC) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The SFC licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +require File.expand_path('../spec_helper', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/cookies', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/headers', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/intercepted_request', __dir__) + +module Selenium + module WebDriver + class BiDi + describe InterceptedRequest do + let(:mock_network) { instance_double(Network) } + let(:mock_request) { {'request' => 'req-123'} } + let(:request_id) { 'req-123' } + let(:intercepted_request) { described_class.new(mock_network, mock_request) } + let(:mock_headers) { [{name: 'Auth', value: 'token'}] } + let(:mock_cookies) { [{name: 'session', value: {type: 'string', value: '123'}}] } + + describe '#continue' do + before do + allow(mock_network).to receive(:continue_request) + end + + it 'sends only the mandatory ID when no optional fields are set' do + expected_payload = {id: request_id, body: nil, cookies: nil, headers: nil, method: nil, url: nil} + intercepted_request.continue + + expect(mock_network).to have_received(:continue_request).with(expected_payload) + end + + it 'sends headers payload when headers are explicitly set' do + intercepted_request.headers = mock_headers + + expected_payload = { + id: request_id, + body: nil, + cookies: nil, + headers: Headers.new(mock_headers).as_json, + method: nil, + url: nil + } + + intercepted_request.continue + + expect(mock_network).to have_received(:continue_request).with(expected_payload) + end + + it 'sends cookies payload when cookies are explicitly set' do + intercepted_request.cookies = mock_cookies + + expected_payload = { + id: request_id, + body: nil, + cookies: Cookies.new(mock_cookies).as_json, + headers: nil, + method: nil, + url: nil + } + + intercepted_request.continue + + expect(mock_network).to have_received(:continue_request).with(expected_payload) + end + + it 'sends full custom payload when all fields are set' do + intercepted_request.headers = mock_headers + intercepted_request.cookies = mock_cookies + intercepted_request.method = 'POST' + + expected_payload = { + id: request_id, + body: nil, + cookies: Cookies.new(mock_cookies).as_json, + headers: Headers.new(mock_headers).as_json, + method: 'POST', + url: nil + } + + intercepted_request.continue + + expect(mock_network).to have_received(:continue_request).with(expected_payload) + end + end + end + end + end +end diff --git a/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb new file mode 100644 index 0000000000000..a6acecffc09f1 --- /dev/null +++ b/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb @@ -0,0 +1,194 @@ +# frozen_string_literal: true + +# Licensed to the Software Freedom Conservancy (SFC) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The SFC licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +require File.expand_path('../spec_helper', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/cookies', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/headers', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/credentials', __dir__) +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network/intercepted_response', __dir__) + +module Selenium + module WebDriver + class BiDi + describe InterceptedResponse do + let(:mock_network) { instance_double(Network) } + let(:response_id) { 'resp-456' } + let(:intercepted_response) { described_class.new(mock_network, {'request' => response_id}) } + let(:mock_headers_data) { [{name: 'Content-Type', value: 'application/json'}] } + let(:mock_cookies_data) { [{name: 'session', value: {type: 'string', value: 'abc'}}] } + let(:mock_body_string) { '{"message": "Access Denied"}' } + + before do + allow(intercepted_response).to receive(:id).and_return(response_id) + end + + describe 'Initialization and Default State' do + it 'has nil headers by default' do + expect(intercepted_response.headers).to be_nil + end + + it 'has nil cookies by default' do + expect(intercepted_response.cookies).to be_nil + end + end + + describe '#continue' do + before do + allow(mock_network).to receive(:continue_response) + end + + it 'sends nil headers and cookies when not explicitly set' do + expected_payload = {id: response_id, cookies: nil, headers: nil, credentials: nil, reason: nil, status: nil} + intercepted_response.continue + + expect(mock_network).to have_received(:continue_response).with(expected_payload) + end + + it 'sends headers payload and uses default nil cookies/credentials' do + intercepted_response.headers = mock_headers_data + reason = 'Custom Reason' + status = 201 + + expected_payload = { + id: response_id, + cookies: nil, + headers: Headers.new(mock_headers_data).as_json, + credentials: nil, + reason: reason, + status: status + } + intercepted_response.reason = reason + intercepted_response.status = status + intercepted_response.continue + + expect(mock_network).to have_received(:continue_response).with(expected_payload) + end + + it 'sends full custom payload when all fields are set' do + credentials = Credentials.new(username: 'user', password: 'pass') + + intercepted_response.headers = mock_headers_data + intercepted_response.cookies = mock_cookies_data + intercepted_response.credentials(username: 'user', password: 'pass') + intercepted_response.reason = 'Test Reason' + intercepted_response.status = 404 + + expected_payload = { + id: response_id, + cookies: Cookies.new(mock_cookies_data).as_json, + headers: Headers.new(mock_headers_data).as_json, + credentials: credentials.as_json, + reason: 'Test Reason', + status: 404 + } + + intercepted_response.continue + + expect(mock_network).to have_received(:continue_response).with(expected_payload) + end + end + + describe '#provide_response' do + before do + allow(mock_network).to receive(:provide_response) + end + + it 'sends nil headers, cookies, and body when not explicitly set' do + expected_payload = {id: response_id, cookies: nil, headers: nil, body: nil, reason: nil, status: nil} + intercepted_response.provide_response + + expect(mock_network).to have_received(:provide_response).with(expected_payload) + end + + it 'sends body payload and uses default nil cookies/headers' do + intercepted_response.body = mock_body_string + reason = 'Provided Success' + status = 200 + + expected_payload = { + id: response_id, + cookies: nil, + headers: nil, + body: {type: 'string', value: mock_body_string.to_json}, + reason: reason, + status: status + } + intercepted_response.reason = reason + intercepted_response.status = status + intercepted_response.provide_response + + expect(mock_network).to have_received(:provide_response).with(expected_payload) + end + + it 'sends full custom payload when all fields are set' do + intercepted_response.headers = mock_headers_data + intercepted_response.cookies = mock_cookies_data + intercepted_response.body = mock_body_string + intercepted_response.reason = 'Forbidden' + intercepted_response.status = 403 + + expected_payload = { + id: response_id, + cookies: Cookies.new(mock_cookies_data).as_json, + headers: Headers.new(mock_headers_data).as_json, + body: {type: 'string', value: mock_body_string.to_json}, + reason: 'Forbidden', + status: 403 + } + + intercepted_response.provide_response + + expect(mock_network).to have_received(:provide_response).with(expected_payload) + end + end + + describe 'setters/getters' do + it '#credentials' do + credentials = intercepted_response.credentials(username: 'u', password: 'p') + expect(credentials).to be_a(Credentials) + expect(intercepted_response.credentials).to be(credentials) + end + + it '#headers=' do + intercepted_response.headers = mock_headers_data + expect(intercepted_response.headers).to be_a(Headers) + end + + it '#cookies=' do + intercepted_response.cookies = mock_cookies_data + first_cookies = intercepted_response.cookies + intercepted_response.cookies = [{name: 'c2', value: 'v2'}] + second_cookies = intercepted_response.cookies + expect(first_cookies).to be(second_cookies) + end + + it '#body=' do + data = {key: 'value', number: 123} + intercepted_response.body = data + expected_body = { + type: 'string', + value: data.to_json + } + expect(intercepted_response.body).to eq(expected_body) + end + end + end + end + end +end From ea1f4f09183bd5e592bbb4dcea87c8a3664704ae Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Fri, 17 Oct 2025 21:49:56 -0500 Subject: [PATCH 4/6] request cookie and header setters now take hashes --- .../selenium/webdriver/bidi/network_spec.rb | 332 ++++++++++++++---- 1 file changed, 254 insertions(+), 78 deletions(-) diff --git a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb index 4b466ea853dec..929e1d13292bc 100644 --- a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb +++ b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb @@ -17,105 +17,281 @@ # specific language governing permissions and limitations # under the License. -require File.expand_path('../spec_helper', __dir__) -# Adjust the require path as necessary for your project structure -require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network', __dir__) +require_relative 'spec_helper' module Selenium module WebDriver - class BiDi - describe Network do - let(:mock_bidi) { instance_double(BiDi, 'Bidi') } - let(:network) { described_class.new(mock_bidi) } - let(:request_id) { '12345-request-id' } + describe Network, exclude: {version: 'beta'}, + exclusive: {bidi: true, reason: 'only executed when bidi is enabled'}, + only: {browser: %i[chrome edge firefox]} do + let(:username) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.first } + let(:password) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.last } - before { allow(mock_bidi).to receive(:send_cmd).and_return({}) } + it 'adds an auth handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(username, password) + driver.navigate.to url_for('basicAuth') + expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') + expect(network.callbacks.count).to be 1 + end + end - describe '#continue_request' do - it 'sends only the mandatory request ID when all optional args are nil' do - expected_payload = {request: request_id} + it 'adds an auth handler with a filter' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(username, password, url_for('basicAuth')) + driver.navigate.to url_for('basicAuth') + expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') + expect(network.callbacks.count).to be 1 + end + end - expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) + it 'adds an auth handler with multiple filters' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(username, password, url_for('basicAuth'), url_for('formPage.html')) + driver.navigate.to url_for('basicAuth') + expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') + expect(network.callbacks.count).to be 1 + end + end - network.continue_request(id: request_id) - end + it 'adds an auth handler with a pattern type' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(username, password, url_for('basicAuth'), pattern_type: :url) + driver.navigate.to url_for('basicAuth') + expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') + expect(network.callbacks.count).to be 1 + end + end - it 'sends only provided optional args' do - expected_payload = { - request: request_id, - body: {type: 'string', value: 'new body'}, - method: 'POST' - } - - expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) - - network.continue_request( - id: request_id, - body: {type: 'string', value: 'new body'}, - cookies: nil, - headers: nil, - method: 'POST' - ) - end + it 'removes an auth handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + id = network.add_authentication_handler(username, password) + network.remove_handler(id) + expect(network.callbacks.count).to be 0 end + end - describe '#continue_response' do - it 'sends only the mandatory request ID when all optional args are nil' do - expected_payload = {request: request_id} + it 'clears all auth handlers' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + 2.times { network.add_authentication_handler(username, password) } + network.clear_handlers + expect(network.callbacks.count).to be 0 + end + end - expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) + it 'continues without auth' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(&:skip) + expect { driver.navigate.to url_for('basicAuth') }.to raise_error(Error::WebDriverError) + end + end - network.continue_response(id: request_id) - end + it 'cancels auth' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_authentication_handler(&:cancel) + driver.navigate.to url_for('basicAuth') + expect(driver.find_element(tag_name: 'pre').text).to eq('Login please') + end + end + + it 'adds a request handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler(&:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a request handler with a filter' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler(url_for('formPage.html'), &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a request handler with multiple filters' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler(url_for('formPage.html'), url_for('basicAuth'), &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a request handler with a pattern type' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler(url_for('formPage.html'), pattern_type: :url, &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end - it 'sends only provided optional args' do - expected_headers = [{name: 'Auth', value: {type: 'string', value: 'Token'}}] - expected_payload = { - request: request_id, - headers: expected_headers, - statusCode: 202 - } - - expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) - - network.continue_response( - id: request_id, - cookies: nil, - credentials: nil, - headers: expected_headers, - reason: nil, - status: 202 - ) + it 'adds a request handler with attributes' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler do |request| + request.method = 'GET' + request.url = url_for('formPage.html') + request.headers = {foo: 'bar', baz: 'qux'} + request.cookies = {name: 'test', + value: 'value4', + domain: 'example.com', + path: '/path', + size: 1234, + httpOnly: true, + secure: true, + sameSite: 'Strict', + expiry: 1234} + request.body = ({test: 'example'}) + request.continue end + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'fails a request' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_request_handler(&:fail) + expect(network.callbacks.count).to be 1 + expect { driver.navigate.to url_for('formPage.html') }.to raise_error(Error::WebDriverError) end + end - describe '#provide_response' do - it 'sends only the mandatory request ID when all optional args are nil' do - expected_payload = {request: request_id} + it 'removes a request handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + id = network.add_request_handler(&:continue) + network.remove_handler(id) + expect(network.callbacks.count).to be 0 + end + end - expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) + it 'clears all request handlers' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + 2.times { network.add_request_handler(&:continue) } + network.clear_handlers + expect(network.callbacks.count).to be 0 + end + end + + it 'adds a response handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler(&:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a response handler with a filter' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler(url_for('formPage.html'), &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.find_element(name: 'login')).to be_displayed + expect(network.callbacks.count).to be 1 + end + end - network.provide_response(id: request_id) + it 'adds a response handler with multiple filters' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler(url_for('formPage.html'), url_for('basicAuth'), &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.find_element(name: 'login')).to be_displayed + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a response handler with a pattern type' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler(url_for('formPage.html'), pattern_type: :url, &:continue) + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end + + it 'adds a response handler with attributes' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler do |response| + response.reason = 'OK' + response.headers = {foo: 'bar'} + response.credentials.username = 'foo' + response.credentials.password = 'bar' + response.cookies = {name: 'foo', + domain: 'localhost', + httpOnly: true, + expiry: '1_000_000', + maxAge: 1_000, + path: '/', + sameSite: 'none', + secure: false} + response.continue end + driver.navigate.to url_for('formPage.html') + expect(driver.current_url).to eq(url_for('formPage.html')) + expect(network.callbacks.count).to be 1 + end + end - it 'sends only provided optional args' do - expected_payload = { - request: request_id, - body: {type: 'string', value: 'Hello'}, - reasonPhrase: 'OK-Custom' - } - - expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) - - network.provide_response( - id: request_id, - body: {type: 'string', value: 'Hello'}, - cookies: nil, - headers: nil, - reason: 'OK-Custom', - status: nil - ) + it 'adds a response handler that provides a response', + except: {browser: :firefox, + reason: 'https://github.com/w3c/webdriver-bidi/issues/747'} do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + network.add_response_handler do |response| + response.status = 200 + response.headers = {foo: 'bar'} + response.body = 'Hello World!' + response.provide_response end + driver.navigate.to url_for('formPage.html') + source = driver.page_source + expect(source).not_to include('There should be a form here:') + expect(source).to include('Hello World!') + end + end + + it 'removes a response handler' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + id = network.add_response_handler(&:continue) + network.remove_handler(id) + network.clear_handlers + expect(network.callbacks.count).to be 0 + end + end + + it 'clears all response handlers' do + reset_driver!(web_socket_url: true) do |driver| + network = described_class.new(driver) + 2.times { network.add_response_handler(&:continue) } + network.clear_handlers + expect(network.callbacks.count).to be 0 end end end From 0f186b9799f71a33ea1f6f3ade0349cd80260fc0 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Fri, 17 Oct 2025 21:55:25 -0500 Subject: [PATCH 5/6] put the unit tests back --- .../selenium/webdriver/bidi/network_spec.rb | 332 ++++-------------- 1 file changed, 78 insertions(+), 254 deletions(-) diff --git a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb index 929e1d13292bc..4b466ea853dec 100644 --- a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb +++ b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb @@ -17,281 +17,105 @@ # specific language governing permissions and limitations # under the License. -require_relative 'spec_helper' +require File.expand_path('../spec_helper', __dir__) +# Adjust the require path as necessary for your project structure +require File.expand_path('../../../../../lib/selenium/webdriver/bidi/network', __dir__) module Selenium module WebDriver - describe Network, exclude: {version: 'beta'}, - exclusive: {bidi: true, reason: 'only executed when bidi is enabled'}, - only: {browser: %i[chrome edge firefox]} do - let(:username) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.first } - let(:password) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.last } + class BiDi + describe Network do + let(:mock_bidi) { instance_double(BiDi, 'Bidi') } + let(:network) { described_class.new(mock_bidi) } + let(:request_id) { '12345-request-id' } - it 'adds an auth handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(username, password) - driver.navigate.to url_for('basicAuth') - expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') - expect(network.callbacks.count).to be 1 - end - end - - it 'adds an auth handler with a filter' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(username, password, url_for('basicAuth')) - driver.navigate.to url_for('basicAuth') - expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') - expect(network.callbacks.count).to be 1 - end - end - - it 'adds an auth handler with multiple filters' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(username, password, url_for('basicAuth'), url_for('formPage.html')) - driver.navigate.to url_for('basicAuth') - expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') - expect(network.callbacks.count).to be 1 - end - end - - it 'adds an auth handler with a pattern type' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(username, password, url_for('basicAuth'), pattern_type: :url) - driver.navigate.to url_for('basicAuth') - expect(driver.find_element(tag_name: 'h1').text).to eq('authorized') - expect(network.callbacks.count).to be 1 - end - end - - it 'removes an auth handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - id = network.add_authentication_handler(username, password) - network.remove_handler(id) - expect(network.callbacks.count).to be 0 - end - end - - it 'clears all auth handlers' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - 2.times { network.add_authentication_handler(username, password) } - network.clear_handlers - expect(network.callbacks.count).to be 0 - end - end - - it 'continues without auth' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(&:skip) - expect { driver.navigate.to url_for('basicAuth') }.to raise_error(Error::WebDriverError) - end - end - - it 'cancels auth' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_authentication_handler(&:cancel) - driver.navigate.to url_for('basicAuth') - expect(driver.find_element(tag_name: 'pre').text).to eq('Login please') - end - end - - it 'adds a request handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler(&:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end - - it 'adds a request handler with a filter' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler(url_for('formPage.html'), &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end + before { allow(mock_bidi).to receive(:send_cmd).and_return({}) } - it 'adds a request handler with multiple filters' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler(url_for('formPage.html'), url_for('basicAuth'), &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end + describe '#continue_request' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} - it 'adds a request handler with a pattern type' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler(url_for('formPage.html'), pattern_type: :url, &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) - it 'adds a request handler with attributes' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler do |request| - request.method = 'GET' - request.url = url_for('formPage.html') - request.headers = {foo: 'bar', baz: 'qux'} - request.cookies = {name: 'test', - value: 'value4', - domain: 'example.com', - path: '/path', - size: 1234, - httpOnly: true, - secure: true, - sameSite: 'Strict', - expiry: 1234} - request.body = ({test: 'example'}) - request.continue + network.continue_request(id: request_id) end - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end - it 'fails a request' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_request_handler(&:fail) - expect(network.callbacks.count).to be 1 - expect { driver.navigate.to url_for('formPage.html') }.to raise_error(Error::WebDriverError) + it 'sends only provided optional args' do + expected_payload = { + request: request_id, + body: {type: 'string', value: 'new body'}, + method: 'POST' + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) + + network.continue_request( + id: request_id, + body: {type: 'string', value: 'new body'}, + cookies: nil, + headers: nil, + method: 'POST' + ) + end end - end - it 'removes a request handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - id = network.add_request_handler(&:continue) - network.remove_handler(id) - expect(network.callbacks.count).to be 0 - end - end + describe '#continue_response' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} - it 'clears all request handlers' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - 2.times { network.add_request_handler(&:continue) } - network.clear_handlers - expect(network.callbacks.count).to be 0 - end - end + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) - it 'adds a response handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler(&:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end + network.continue_response(id: request_id) + end - it 'adds a response handler with a filter' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler(url_for('formPage.html'), &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.find_element(name: 'login')).to be_displayed - expect(network.callbacks.count).to be 1 + it 'sends only provided optional args' do + expected_headers = [{name: 'Auth', value: {type: 'string', value: 'Token'}}] + expected_payload = { + request: request_id, + headers: expected_headers, + statusCode: 202 + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) + + network.continue_response( + id: request_id, + cookies: nil, + credentials: nil, + headers: expected_headers, + reason: nil, + status: 202 + ) + end end - end - it 'adds a response handler with multiple filters' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler(url_for('formPage.html'), url_for('basicAuth'), &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.find_element(name: 'login')).to be_displayed - expect(network.callbacks.count).to be 1 - end - end + describe '#provide_response' do + it 'sends only the mandatory request ID when all optional args are nil' do + expected_payload = {request: request_id} - it 'adds a response handler with a pattern type' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler(url_for('formPage.html'), pattern_type: :url, &:continue) - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) - it 'adds a response handler with attributes' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler do |response| - response.reason = 'OK' - response.headers = {foo: 'bar'} - response.credentials.username = 'foo' - response.credentials.password = 'bar' - response.cookies = {name: 'foo', - domain: 'localhost', - httpOnly: true, - expiry: '1_000_000', - maxAge: 1_000, - path: '/', - sameSite: 'none', - secure: false} - response.continue + network.provide_response(id: request_id) end - driver.navigate.to url_for('formPage.html') - expect(driver.current_url).to eq(url_for('formPage.html')) - expect(network.callbacks.count).to be 1 - end - end - it 'adds a response handler that provides a response', - except: {browser: :firefox, - reason: 'https://github.com/w3c/webdriver-bidi/issues/747'} do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - network.add_response_handler do |response| - response.status = 200 - response.headers = {foo: 'bar'} - response.body = 'Hello World!' - response.provide_response + it 'sends only provided optional args' do + expected_payload = { + request: request_id, + body: {type: 'string', value: 'Hello'}, + reasonPhrase: 'OK-Custom' + } + + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) + + network.provide_response( + id: request_id, + body: {type: 'string', value: 'Hello'}, + cookies: nil, + headers: nil, + reason: 'OK-Custom', + status: nil + ) end - driver.navigate.to url_for('formPage.html') - source = driver.page_source - expect(source).not_to include('There should be a form here:') - expect(source).to include('Hello World!') - end - end - - it 'removes a response handler' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - id = network.add_response_handler(&:continue) - network.remove_handler(id) - network.clear_handlers - expect(network.callbacks.count).to be 0 - end - end - - it 'clears all response handlers' do - reset_driver!(web_socket_url: true) do |driver| - network = described_class.new(driver) - 2.times { network.add_response_handler(&:continue) } - network.clear_handlers - expect(network.callbacks.count).to be 0 end end end From 396d55ab6334de502baa8f5576e561add6f518c9 Mon Sep 17 00:00:00 2001 From: aguspe Date: Sat, 18 Oct 2025 20:24:54 +0200 Subject: [PATCH 6/6] All tests fixed --- .../bidi/network/intercepted_request.rb | 16 ++++++++++--- .../bidi/network/intercepted_response.rb | 22 +++++++++++++---- .../lib/selenium/webdriver/bidi/network.rbs | 2 +- .../webdriver/bidi/network/cookies.rbs | 2 +- .../bidi/intercepted_response_spec.rb | 10 ++++---- .../selenium/webdriver/bidi/network_spec.rb | 24 +++++++++---------- 6 files changed, 49 insertions(+), 27 deletions(-) diff --git a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb index b7d66e2fde94f..f87c99d620252 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb @@ -25,7 +25,7 @@ module WebDriver class BiDi class InterceptedRequest < InterceptedItem attr_accessor :method, :url - attr_reader :body, :headers, :cookies + attr_reader :body def initialize(network, request) super @@ -37,11 +37,13 @@ def initialize(network, request) end def continue + cookies = @cookies&.as_json + headers = @headers&.as_json network.continue_request( id: id, body: body, - cookies: cookies&.as_json, - headers: headers&.as_json, + cookies: cookies, + headers: headers, method: method, url: url ) @@ -62,6 +64,14 @@ def headers=(headers = {}) @headers = Headers.new(headers) end + def headers(headers = {}) + @headers ||= Headers.new(headers) + end + + def cookies(cookies = {}) + @cookies ||= Cookies.new(cookies) + end + 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 9fed545a4e73e..433c9edcadb23 100644 --- a/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb +++ b/rb/lib/selenium/webdriver/bidi/network/intercepted_response.rb @@ -26,7 +26,7 @@ module WebDriver class BiDi class InterceptedResponse < InterceptedItem attr_accessor :reason, :status - attr_reader :body, :headers, :cookies + attr_reader :body def initialize(network, request) super @@ -38,10 +38,12 @@ def initialize(network, request) end def continue + cookies = @cookies&.as_json + headers = @headers&.as_json network.continue_response( id: id, - cookies: cookies&.as_json, - headers: headers&.as_json, + cookies: cookies, + headers: headers, credentials: credentials.as_json, reason: reason, status: status @@ -49,10 +51,12 @@ def continue end def provide_response + cookies = @cookies&.as_json + headers = @headers&.as_json network.provide_response( id: id, - cookies: cookies&.as_json, - headers: headers&.as_json, + cookies: cookies, + headers: headers, body: body, reason: reason, status: status @@ -63,10 +67,18 @@ def credentials(username: nil, password: nil) @credentials ||= Credentials.new(username: username, password: password) end + def headers(headers = {}) + @headers ||= Headers.new(headers) + end + def headers=(*headers) @headers = Headers.new(headers) end + def cookies(cookies = {}) + @cookies ||= Cookies.new(cookies) + end + def cookies=(cookies = {}) @cookies ||= Cookies.new(cookies) end diff --git a/rb/sig/lib/selenium/webdriver/bidi/network.rbs b/rb/sig/lib/selenium/webdriver/bidi/network.rbs index e660f684d9ffd..bc286a14b245d 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/network.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/network.rbs @@ -24,7 +24,7 @@ module Selenium def remove_intercept: (String intercept) -> Hash[nil, nil] - def continue_with_auth: (String request_id, String username, String password) -> Hash[nil, nil] + def continue_with_auth: (Integer request_id, String username, String password) -> Hash[nil, nil] def provide_response: -> Hash[nil, nil] diff --git a/rb/sig/lib/selenium/webdriver/bidi/network/cookies.rbs b/rb/sig/lib/selenium/webdriver/bidi/network/cookies.rbs index 5688a4e9b63cc..4d735480e64a7 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/network/cookies.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/network/cookies.rbs @@ -2,7 +2,7 @@ module Selenium module WebDriver class BiDi class Cookies - def initialize: (Hash[Symbol, String | Integer | bool] cookies) -> void + def initialize: (Hash[Symbol, String | Integer | bool]? cookies) -> void def as_json: () -> Array[Hash[Symbol, untyped]] end diff --git a/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb index a6acecffc09f1..8895c59f3520b 100644 --- a/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb +++ b/rb/spec/unit/selenium/webdriver/bidi/intercepted_response_spec.rb @@ -39,12 +39,12 @@ class BiDi end describe 'Initialization and Default State' do - it 'has nil headers by default' do - expect(intercepted_response.headers).to be_nil + it 'has an empty hash as headers by default' do + expect(intercepted_response.headers).to be_empty end - it 'has nil cookies by default' do - expect(intercepted_response.cookies).to be_nil + it 'has an empty hash as cookies by default' do + expect(intercepted_response.cookies).to be_empty end end @@ -116,7 +116,7 @@ class BiDi expect(mock_network).to have_received(:provide_response).with(expected_payload) end - it 'sends body payload and uses default nil cookies/headers' do + it 'sends body payload and uses default [] cookies/headers' do intercepted_response.body = mock_body_string reason = 'Provided Success' status = 200 diff --git a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb index 4b466ea853dec..ca4f4dcf6191e 100644 --- a/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb +++ b/rb/spec/unit/selenium/webdriver/bidi/network_spec.rb @@ -35,9 +35,9 @@ class BiDi it 'sends only the mandatory request ID when all optional args are nil' do expected_payload = {request: request_id} - expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) - network.continue_request(id: request_id) + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) end it 'sends only provided optional args' do @@ -47,8 +47,6 @@ class BiDi method: 'POST' } - expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) - network.continue_request( id: request_id, body: {type: 'string', value: 'new body'}, @@ -56,6 +54,8 @@ class BiDi headers: nil, method: 'POST' ) + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueRequest', expected_payload) end end @@ -63,9 +63,9 @@ class BiDi it 'sends only the mandatory request ID when all optional args are nil' do expected_payload = {request: request_id} - expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) - network.continue_response(id: request_id) + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) end it 'sends only provided optional args' do @@ -76,8 +76,6 @@ class BiDi statusCode: 202 } - expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) - network.continue_response( id: request_id, cookies: nil, @@ -86,6 +84,8 @@ class BiDi reason: nil, status: 202 ) + + expect(mock_bidi).to have_received(:send_cmd).with('network.continueResponse', expected_payload) end end @@ -93,9 +93,9 @@ class BiDi it 'sends only the mandatory request ID when all optional args are nil' do expected_payload = {request: request_id} - expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) - network.provide_response(id: request_id) + + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) end it 'sends only provided optional args' do @@ -105,8 +105,6 @@ class BiDi reasonPhrase: 'OK-Custom' } - expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) - network.provide_response( id: request_id, body: {type: 'string', value: 'Hello'}, @@ -115,6 +113,8 @@ class BiDi reason: 'OK-Custom', status: nil ) + + expect(mock_bidi).to have_received(:send_cmd).with('network.provideResponse', expected_payload) end end end