ferrum 0.11 → 0.13
Sign up to get free protection for your applications and to get access to all the features.
- 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
|