ferrum 0.11 → 0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +174 -30
- data/lib/ferrum/browser/binary.rb +46 -0
- data/lib/ferrum/browser/client.rb +17 -16
- data/lib/ferrum/browser/command.rb +10 -12
- data/lib/ferrum/browser/options/base.rb +2 -11
- data/lib/ferrum/browser/options/chrome.rb +29 -18
- data/lib/ferrum/browser/options/firefox.rb +13 -9
- data/lib/ferrum/browser/options.rb +84 -0
- data/lib/ferrum/browser/process.rb +45 -40
- data/lib/ferrum/browser/subscriber.rb +1 -3
- data/lib/ferrum/browser/version_info.rb +71 -0
- data/lib/ferrum/browser/web_socket.rb +9 -12
- data/lib/ferrum/browser/xvfb.rb +4 -8
- data/lib/ferrum/browser.rb +193 -47
- data/lib/ferrum/context.rb +9 -4
- data/lib/ferrum/contexts.rb +12 -10
- data/lib/ferrum/cookies/cookie.rb +126 -0
- data/lib/ferrum/cookies.rb +93 -55
- data/lib/ferrum/dialog.rb +30 -0
- data/lib/ferrum/errors.rb +115 -0
- data/lib/ferrum/frame/dom.rb +177 -0
- data/lib/ferrum/frame/runtime.rb +58 -75
- data/lib/ferrum/frame.rb +118 -23
- data/lib/ferrum/headers.rb +30 -2
- data/lib/ferrum/keyboard.rb +56 -13
- data/lib/ferrum/mouse.rb +92 -7
- data/lib/ferrum/network/auth_request.rb +7 -2
- data/lib/ferrum/network/exchange.rb +97 -12
- data/lib/ferrum/network/intercepted_request.rb +10 -8
- data/lib/ferrum/network/request.rb +69 -0
- data/lib/ferrum/network/response.rb +85 -3
- data/lib/ferrum/network.rb +285 -36
- data/lib/ferrum/node.rb +69 -23
- data/lib/ferrum/page/animation.rb +16 -1
- data/lib/ferrum/page/frames.rb +111 -30
- data/lib/ferrum/page/screenshot.rb +142 -65
- data/lib/ferrum/page/stream.rb +38 -0
- data/lib/ferrum/page/tracing.rb +97 -0
- data/lib/ferrum/page.rb +224 -60
- data/lib/ferrum/proxy.rb +147 -0
- data/lib/ferrum/{rbga.rb → rgba.rb} +4 -2
- data/lib/ferrum/target.rb +7 -4
- data/lib/ferrum/utils/attempt.rb +20 -0
- data/lib/ferrum/utils/elapsed_time.rb +27 -0
- data/lib/ferrum/utils/platform.rb +28 -0
- data/lib/ferrum/version.rb +1 -1
- data/lib/ferrum.rb +4 -146
- metadata +63 -51
@@ -9,7 +9,8 @@ module Ferrum
|
|
9
9
|
|
10
10
|
def initialize(page, params)
|
11
11
|
@status = nil
|
12
|
-
@page
|
12
|
+
@page = page
|
13
|
+
@params = params
|
13
14
|
@request_id = params["requestId"]
|
14
15
|
@frame_id = params["frameId"]
|
15
16
|
@resource_type = params["resourceType"]
|
@@ -30,15 +31,12 @@ module Ferrum
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def respond(**options)
|
33
|
-
has_body = options.
|
34
|
+
has_body = options.key?(:body)
|
34
35
|
headers = has_body ? { "content-length" => options.fetch(:body, "").length } : {}
|
35
36
|
headers = headers.merge(options.fetch(:responseHeaders, {}))
|
36
37
|
|
37
|
-
options = {responseCode: 200}.merge(options)
|
38
|
-
options = options.merge(
|
39
|
-
requestId: request_id,
|
40
|
-
responseHeaders: header_array(headers),
|
41
|
-
})
|
38
|
+
options = { responseCode: 200 }.merge(options)
|
39
|
+
options = options.merge(requestId: request_id, responseHeaders: header_array(headers))
|
42
40
|
options = options.merge(body: Base64.strict_encode64(options.fetch(:body, ""))) if has_body
|
43
41
|
|
44
42
|
@status = :responded
|
@@ -77,7 +75,11 @@ module Ferrum
|
|
77
75
|
end
|
78
76
|
|
79
77
|
def inspect
|
80
|
-
|
78
|
+
"#<#{self.class} " \
|
79
|
+
"@request_id=#{@request_id.inspect} " \
|
80
|
+
"@frame_id=#{@frame_id.inspect} " \
|
81
|
+
"@resource_type=#{@resource_type.inspect} " \
|
82
|
+
"@request=#{@request.inspect}>"
|
81
83
|
end
|
82
84
|
|
83
85
|
private
|
@@ -4,47 +4,116 @@ require "time"
|
|
4
4
|
|
5
5
|
module Ferrum
|
6
6
|
class Network
|
7
|
+
#
|
8
|
+
# Represents a [Network.Request](https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-Request)
|
9
|
+
# object.
|
10
|
+
#
|
7
11
|
class Request
|
12
|
+
#
|
13
|
+
# Initializes the request object.
|
14
|
+
#
|
15
|
+
# @param [Hash{String => Object}] params
|
16
|
+
# The parsed JSON attributes.
|
17
|
+
#
|
8
18
|
def initialize(params)
|
9
19
|
@params = params
|
10
20
|
@request = @params["request"]
|
11
21
|
end
|
12
22
|
|
23
|
+
#
|
24
|
+
# The request ID.
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
#
|
13
28
|
def id
|
14
29
|
@params["requestId"]
|
15
30
|
end
|
16
31
|
|
32
|
+
#
|
33
|
+
# The request resouce type.
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
#
|
17
37
|
def type
|
18
38
|
@params["type"]
|
19
39
|
end
|
20
40
|
|
41
|
+
#
|
42
|
+
# Determines if the request is of the given type.
|
43
|
+
#
|
44
|
+
# @param [String, Symbol] value
|
45
|
+
# The type value to compare against.
|
46
|
+
#
|
47
|
+
# @return [Boolean]
|
48
|
+
#
|
21
49
|
def type?(value)
|
22
50
|
type.downcase == value.to_s.downcase
|
23
51
|
end
|
24
52
|
|
53
|
+
#
|
54
|
+
# The frame ID of the request.
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
#
|
25
58
|
def frame_id
|
26
59
|
@params["frameId"]
|
27
60
|
end
|
28
61
|
|
62
|
+
#
|
63
|
+
# The URL for the request.
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
#
|
29
67
|
def url
|
30
68
|
@request["url"]
|
31
69
|
end
|
32
70
|
|
71
|
+
#
|
72
|
+
# The URL fragment for the request.
|
73
|
+
#
|
74
|
+
# @return [String, nil]
|
75
|
+
#
|
33
76
|
def url_fragment
|
34
77
|
@request["urlFragment"]
|
35
78
|
end
|
36
79
|
|
80
|
+
#
|
81
|
+
# The request method.
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
#
|
37
85
|
def method
|
38
86
|
@request["method"]
|
39
87
|
end
|
40
88
|
|
89
|
+
#
|
90
|
+
# The request headers.
|
91
|
+
#
|
92
|
+
# @return [Hash{String => String}]
|
93
|
+
#
|
41
94
|
def headers
|
42
95
|
@request["headers"]
|
43
96
|
end
|
44
97
|
|
98
|
+
#
|
99
|
+
# The request timestamp.
|
100
|
+
#
|
101
|
+
# @return [Time]
|
102
|
+
#
|
45
103
|
def time
|
46
104
|
@time ||= Time.strptime(@params["wallTime"].to_s, "%s")
|
47
105
|
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# The optional HTTP `POST` form data.
|
109
|
+
#
|
110
|
+
# @return [String, nil]
|
111
|
+
# The HTTP `POST` form data.
|
112
|
+
#
|
113
|
+
def post_data
|
114
|
+
@request["postData"]
|
115
|
+
end
|
116
|
+
alias body post_data
|
48
117
|
end
|
49
118
|
end
|
50
119
|
end
|
@@ -2,43 +2,105 @@
|
|
2
2
|
|
3
3
|
module Ferrum
|
4
4
|
class Network
|
5
|
+
#
|
6
|
+
# Represents a [Network.Response](https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-Response)
|
7
|
+
# object.
|
8
|
+
#
|
5
9
|
class Response
|
10
|
+
# The response body size.
|
11
|
+
#
|
12
|
+
# @return [Integer, nil]
|
6
13
|
attr_reader :body_size
|
7
14
|
|
15
|
+
# The parsed JSON attributes for the [Network.Response](https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-Response)
|
16
|
+
# object.
|
17
|
+
#
|
18
|
+
# @return [Hash{String => Object}]
|
19
|
+
attr_reader :params
|
20
|
+
|
21
|
+
#
|
22
|
+
# Initializes the respones object.
|
23
|
+
#
|
24
|
+
# @param [Page] page
|
25
|
+
# The page associated with the network response.
|
26
|
+
#
|
27
|
+
# @param [Hash{String => Object}] params
|
28
|
+
# The parsed JSON attributes for the [Network.Response](https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-Response)
|
29
|
+
#
|
8
30
|
def initialize(page, params)
|
9
31
|
@page = page
|
10
32
|
@params = params
|
11
33
|
@response = params["response"] || params["redirectResponse"]
|
12
34
|
end
|
13
35
|
|
36
|
+
#
|
37
|
+
# The request ID associated with the response.
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
#
|
14
41
|
def id
|
15
42
|
@params["requestId"]
|
16
43
|
end
|
17
44
|
|
45
|
+
#
|
46
|
+
# The URL of the response.
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
#
|
18
50
|
def url
|
19
51
|
@response["url"]
|
20
52
|
end
|
21
53
|
|
54
|
+
#
|
55
|
+
# The HTTP status of the response.
|
56
|
+
#
|
57
|
+
# @return [Integer]
|
58
|
+
#
|
22
59
|
def status
|
23
60
|
@response["status"]
|
24
61
|
end
|
25
62
|
|
63
|
+
#
|
64
|
+
# The HTTP status text.
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
#
|
26
68
|
def status_text
|
27
69
|
@response["statusText"]
|
28
70
|
end
|
29
71
|
|
72
|
+
#
|
73
|
+
# The headers of the response.
|
74
|
+
#
|
75
|
+
# @return [Hash{String => String}]
|
76
|
+
#
|
30
77
|
def headers
|
31
78
|
@response["headers"]
|
32
79
|
end
|
33
80
|
|
81
|
+
#
|
82
|
+
# The total size in bytes of the response.
|
83
|
+
#
|
84
|
+
# @return [Integer]
|
85
|
+
#
|
34
86
|
def headers_size
|
35
87
|
@response["encodedDataLength"]
|
36
88
|
end
|
37
|
-
|
89
|
+
|
90
|
+
#
|
91
|
+
# The resource type of the response.
|
92
|
+
#
|
93
|
+
# @return [String]
|
94
|
+
#
|
38
95
|
def type
|
39
96
|
@params["type"]
|
40
97
|
end
|
41
98
|
|
99
|
+
#
|
100
|
+
# The `Content-Type` header value of the response.
|
101
|
+
#
|
102
|
+
# @return [String, nil]
|
103
|
+
#
|
42
104
|
def content_type
|
43
105
|
@content_type ||= headers.find { |k, _| k.downcase == "content-type" }&.last&.sub(/;.*\z/, "")
|
44
106
|
end
|
@@ -52,23 +114,43 @@ module Ferrum
|
|
52
114
|
@body_size = size - headers_size
|
53
115
|
end
|
54
116
|
|
117
|
+
#
|
118
|
+
# The response body.
|
119
|
+
#
|
120
|
+
# @return [String]
|
121
|
+
#
|
55
122
|
def body
|
56
123
|
@body ||= begin
|
57
124
|
body, encoded = @page
|
58
|
-
|
59
|
-
|
125
|
+
.command("Network.getResponseBody", requestId: id)
|
126
|
+
.values_at("body", "base64Encoded")
|
60
127
|
encoded ? Base64.decode64(body) : body
|
61
128
|
end
|
62
129
|
end
|
63
130
|
|
131
|
+
#
|
132
|
+
# @return [Boolean]
|
133
|
+
#
|
64
134
|
def main?
|
65
135
|
@page.network.response == self
|
66
136
|
end
|
67
137
|
|
138
|
+
#
|
139
|
+
# Comapres the respones ID to another response's ID.
|
140
|
+
#
|
141
|
+
# @return [Boolean]
|
142
|
+
# Indicates whether the response has the same ID as the other response
|
143
|
+
# object.
|
144
|
+
#
|
68
145
|
def ==(other)
|
69
146
|
id == other.id
|
70
147
|
end
|
71
148
|
|
149
|
+
#
|
150
|
+
# Inspects the response object.
|
151
|
+
#
|
152
|
+
# @return [String]
|
153
|
+
#
|
72
154
|
def inspect
|
73
155
|
%(#<#{self.class} @params=#{@params.inspect} @response=#{@response.inspect}>)
|
74
156
|
end
|