Skip to content

Commit 1dd967e

Browse files
authored
[rb] Add Bidi Network Response Handler (#14900)
1 parent 52641fc commit 1dd967e

29 files changed

+1217
-61
lines changed

rb/lib/selenium/webdriver/bidi.rb

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class BiDi
2626
autoload :BrowsingContext, 'selenium/webdriver/bidi/browsing_context'
2727
autoload :Struct, 'selenium/webdriver/bidi/struct'
2828
autoload :Network, 'selenium/webdriver/bidi/network'
29+
autoload :InterceptedRequest, 'selenium/webdriver/bidi/network/intercepted_request'
30+
autoload :InterceptedResponse, 'selenium/webdriver/bidi/network/intercepted_response'
31+
autoload :InterceptedAuth, 'selenium/webdriver/bidi/network/intercepted_auth'
32+
autoload :InterceptedItem, 'selenium/webdriver/bidi/network/intercepted_item'
2933

3034
def initialize(url:)
3135
@ws = WebSocketConnection.new(url: url)

rb/lib/selenium/webdriver/bidi/network.rb

+57-16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# KIND, either express or implied. See the License for the
1717
# specific language governing permissions and limitations
1818
# under the License.
19+
require_relative 'network/url_pattern'
1920

2021
module Selenium
2122
module WebDriver
@@ -39,8 +40,12 @@ def initialize(bidi)
3940
@bidi = bidi
4041
end
4142

42-
def add_intercept(phases: [], contexts: nil, url_patterns: nil)
43-
@bidi.send_cmd('network.addIntercept', phases: phases, contexts: contexts, urlPatterns: url_patterns)
43+
def add_intercept(phases: [], contexts: nil, url_patterns: nil, pattern_type: :string)
44+
url_patterns = url_patterns && pattern_type ? UrlPattern.format_pattern(url_patterns, pattern_type) : nil
45+
@bidi.send_cmd('network.addIntercept',
46+
phases: phases,
47+
contexts: contexts,
48+
urlPatterns: url_patterns)
4449
end
4550

4651
def remove_intercept(intercept)
@@ -50,31 +55,67 @@ def remove_intercept(intercept)
5055
def continue_with_auth(request_id, username, password)
5156
@bidi.send_cmd(
5257
'network.continueWithAuth',
53-
'request' => request_id,
54-
'action' => 'provideCredentials',
55-
'credentials' => {
56-
'type' => 'password',
57-
'username' => username,
58-
'password' => password
58+
request: request_id,
59+
action: 'provideCredentials',
60+
credentials: {
61+
type: 'password',
62+
username: username,
63+
password: password
5964
}
6065
)
6166
end
6267

63-
def continue_with_request(**args)
68+
def continue_without_auth(request_id)
6469
@bidi.send_cmd(
65-
'network.continueWithRequest',
66-
request: args[:request_id],
67-
'body' => args[:body],
68-
'cookies' => args[:cookies],
69-
'headers' => args[:headers],
70-
'method' => args[:method],
71-
'url' => args[:url]
70+
'network.continueWithAuth',
71+
request: request_id,
72+
action: 'default'
73+
)
74+
end
75+
76+
def cancel_auth(request_id)
77+
@bidi.send_cmd(
78+
'network.continueWithAuth',
79+
request: request_id,
80+
action: 'cancel'
81+
)
82+
end
83+
84+
def continue_request(**args)
85+
@bidi.send_cmd(
86+
'network.continueRequest',
87+
request: args[:id],
88+
body: args[:body],
89+
cookies: args[:cookies],
90+
headers: args[:headers],
91+
method: args[:method],
92+
url: args[:url]
93+
)
94+
end
95+
96+
def fail_request(request_id)
97+
@bidi.send_cmd(
98+
'network.failRequest',
99+
request: request_id
100+
)
101+
end
102+
103+
def continue_response(**args)
104+
@bidi.send_cmd(
105+
'network.continueResponse',
106+
request: args[:id],
107+
cookies: args[:cookies],
108+
credentials: args[:credentials],
109+
headers: args[:headers],
110+
reasonPhrase: args[:reason],
111+
statusCode: args[:status]
72112
)
73113
end
74114

75115
def on(event, &)
76116
event = EVENTS[event] if event.is_a?(Symbol)
77117
@bidi.add_callback(event, &)
118+
@bidi.session.subscribe(event)
78119
end
79120
end # Network
80121
end # BiDi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
class BiDi
23+
class Cookies < Hash
24+
def initialize(cookies = {})
25+
super()
26+
merge!(cookies)
27+
end
28+
29+
def as_json
30+
self[:name] = self[:name].to_s
31+
self[:value] = {type: 'string', value: self[:value].to_s}
32+
33+
[compact]
34+
end
35+
end
36+
end # BiDi
37+
end # WebDriver
38+
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
class BiDi
23+
class Credentials
24+
attr_accessor :username, :password
25+
26+
def initialize(username: nil, password: nil)
27+
@username = username
28+
@password = password
29+
end
30+
31+
def as_json
32+
return nil unless username && password
33+
34+
{
35+
type: 'password',
36+
username: username,
37+
password: password
38+
}
39+
end
40+
end
41+
end # BiDi
42+
end # WebDriver
43+
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
class BiDi
23+
class Headers < Hash
24+
def as_json
25+
map do |name, val|
26+
{
27+
name: name.to_s,
28+
value: {
29+
type: 'string',
30+
value: val.to_s
31+
}
32+
}
33+
end
34+
end
35+
end
36+
end # BiDi
37+
end # WebDriver
38+
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
class BiDi
23+
class InterceptedAuth < InterceptedItem
24+
def authenticate(username, password)
25+
network.continue_with_auth(id, username, password)
26+
end
27+
28+
def skip
29+
network.continue_without_auth(id)
30+
end
31+
32+
def cancel
33+
network.cancel_auth(id)
34+
end
35+
end
36+
end # BiDi
37+
end # WebDriver
38+
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
class BiDi
23+
class InterceptedItem
24+
attr_reader :network, :request
25+
26+
def initialize(network, request)
27+
@network = network
28+
@request = request
29+
end
30+
31+
def id
32+
@id ||= @request['request']
33+
end
34+
end
35+
end # BiDi
36+
end # WebDriver
37+
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
require_relative 'cookies'
21+
require_relative 'headers'
22+
23+
module Selenium
24+
module WebDriver
25+
class BiDi
26+
class InterceptedRequest < InterceptedItem
27+
attr_accessor :method, :url
28+
attr_reader :body
29+
30+
def initialize(network, request)
31+
super
32+
@method = nil
33+
@url = nil
34+
@body = nil
35+
end
36+
37+
def continue
38+
network.continue_request(
39+
id: id,
40+
body: body,
41+
cookies: cookies.as_json,
42+
headers: headers.as_json,
43+
method: method,
44+
url: url
45+
)
46+
end
47+
48+
def fail
49+
network.fail_request(id)
50+
end
51+
52+
def body=(value)
53+
@body = {
54+
type: 'string',
55+
value: value.to_json
56+
}
57+
end
58+
59+
def headers
60+
@headers ||= Headers.new
61+
end
62+
63+
def cookies(cookies = {})
64+
@cookies ||= Cookies.new(cookies)
65+
end
66+
end
67+
end # BiDi
68+
end # WebDriver
69+
end # Selenium

0 commit comments

Comments
 (0)