Skip to content

Commit

Permalink
[rb] Add Bidi Network Response Handler (#14900)
Browse files Browse the repository at this point in the history
  • Loading branch information
aguspe authored Jan 23, 2025
1 parent 52641fc commit 1dd967e
Show file tree
Hide file tree
Showing 29 changed files with 1,217 additions and 61 deletions.
4 changes: 4 additions & 0 deletions rb/lib/selenium/webdriver/bidi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class BiDi
autoload :BrowsingContext, 'selenium/webdriver/bidi/browsing_context'
autoload :Struct, 'selenium/webdriver/bidi/struct'
autoload :Network, 'selenium/webdriver/bidi/network'
autoload :InterceptedRequest, 'selenium/webdriver/bidi/network/intercepted_request'
autoload :InterceptedResponse, 'selenium/webdriver/bidi/network/intercepted_response'
autoload :InterceptedAuth, 'selenium/webdriver/bidi/network/intercepted_auth'
autoload :InterceptedItem, 'selenium/webdriver/bidi/network/intercepted_item'

def initialize(url:)
@ws = WebSocketConnection.new(url: url)
Expand Down
73 changes: 57 additions & 16 deletions rb/lib/selenium/webdriver/bidi/network.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require_relative 'network/url_pattern'

module Selenium
module WebDriver
Expand All @@ -39,8 +40,12 @@ def initialize(bidi)
@bidi = bidi
end

def add_intercept(phases: [], contexts: nil, url_patterns: nil)
@bidi.send_cmd('network.addIntercept', phases: phases, contexts: contexts, urlPatterns: url_patterns)
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',
phases: phases,
contexts: contexts,
urlPatterns: url_patterns)
end

def remove_intercept(intercept)
Expand All @@ -50,31 +55,67 @@ def remove_intercept(intercept)
def continue_with_auth(request_id, username, password)
@bidi.send_cmd(
'network.continueWithAuth',
'request' => request_id,
'action' => 'provideCredentials',
'credentials' => {
'type' => 'password',
'username' => username,
'password' => password
request: request_id,
action: 'provideCredentials',
credentials: {
type: 'password',
username: username,
password: password
}
)
end

def continue_with_request(**args)
def continue_without_auth(request_id)
@bidi.send_cmd(
'network.continueWithRequest',
request: args[:request_id],
'body' => args[:body],
'cookies' => args[:cookies],
'headers' => args[:headers],
'method' => args[:method],
'url' => args[:url]
'network.continueWithAuth',
request: request_id,
action: 'default'
)
end

def cancel_auth(request_id)
@bidi.send_cmd(
'network.continueWithAuth',
request: request_id,
action: 'cancel'
)
end

def continue_request(**args)
@bidi.send_cmd(
'network.continueRequest',
request: args[:id],
body: args[:body],
cookies: args[:cookies],
headers: args[:headers],
method: args[:method],
url: args[:url]
)
end

def fail_request(request_id)
@bidi.send_cmd(
'network.failRequest',
request: request_id
)
end

def continue_response(**args)
@bidi.send_cmd(
'network.continueResponse',
request: args[:id],
cookies: args[:cookies],
credentials: args[:credentials],
headers: args[:headers],
reasonPhrase: args[:reason],
statusCode: args[:status]
)
end

def on(event, &)
event = EVENTS[event] if event.is_a?(Symbol)
@bidi.add_callback(event, &)
@bidi.session.subscribe(event)
end
end # Network
end # BiDi
Expand Down
38 changes: 38 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/cookies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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.

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}

[compact]
end
end
end # BiDi
end # WebDriver
end # Selenium
43 changes: 43 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/credentials.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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.

module Selenium
module WebDriver
class BiDi
class Credentials
attr_accessor :username, :password

def initialize(username: nil, password: nil)
@username = username
@password = password
end

def as_json
return nil unless username && password

{
type: 'password',
username: username,
password: password
}
end
end
end # BiDi
end # WebDriver
end # Selenium
38 changes: 38 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/headers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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.

module Selenium
module WebDriver
class BiDi
class Headers < Hash
def as_json
map do |name, val|
{
name: name.to_s,
value: {
type: 'string',
value: val.to_s
}
}
end
end
end
end # BiDi
end # WebDriver
end # Selenium
38 changes: 38 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/intercepted_auth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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.

module Selenium
module WebDriver
class BiDi
class InterceptedAuth < InterceptedItem
def authenticate(username, password)
network.continue_with_auth(id, username, password)
end

def skip
network.continue_without_auth(id)
end

def cancel
network.cancel_auth(id)
end
end
end # BiDi
end # WebDriver
end # Selenium
37 changes: 37 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/intercepted_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 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.

module Selenium
module WebDriver
class BiDi
class InterceptedItem
attr_reader :network, :request

def initialize(network, request)
@network = network
@request = request
end

def id
@id ||= @request['request']
end
end
end # BiDi
end # WebDriver
end # Selenium
69 changes: 69 additions & 0 deletions rb/lib/selenium/webdriver/bidi/network/intercepted_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 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_relative 'cookies'
require_relative 'headers'

module Selenium
module WebDriver
class BiDi
class InterceptedRequest < InterceptedItem
attr_accessor :method, :url
attr_reader :body

def initialize(network, request)
super
@method = nil
@url = nil
@body = nil
end

def continue
network.continue_request(
id: id,
body: body,
cookies: cookies.as_json,
headers: headers.as_json,
method: method,
url: url
)
end

def fail
network.fail_request(id)
end

def body=(value)
@body = {
type: 'string',
value: value.to_json
}
end

def headers
@headers ||= Headers.new
end

def cookies(cookies = {})
@cookies ||= Cookies.new(cookies)
end
end
end # BiDi
end # WebDriver
end # Selenium
Loading

0 comments on commit 1dd967e

Please sign in to comment.