ferrum 0.13 → 0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +288 -154
  4. data/lib/ferrum/browser/command.rb +8 -0
  5. data/lib/ferrum/browser/options/chrome.rb +17 -5
  6. data/lib/ferrum/browser/options.rb +38 -25
  7. data/lib/ferrum/browser/process.rb +44 -17
  8. data/lib/ferrum/browser.rb +34 -52
  9. data/lib/ferrum/client/subscriber.rb +76 -0
  10. data/lib/ferrum/{browser → client}/web_socket.rb +36 -22
  11. data/lib/ferrum/client.rb +169 -0
  12. data/lib/ferrum/context.rb +19 -15
  13. data/lib/ferrum/contexts.rb +46 -12
  14. data/lib/ferrum/cookies/cookie.rb +57 -0
  15. data/lib/ferrum/cookies.rb +40 -4
  16. data/lib/ferrum/downloads.rb +60 -0
  17. data/lib/ferrum/errors.rb +2 -1
  18. data/lib/ferrum/frame.rb +1 -0
  19. data/lib/ferrum/headers.rb +1 -1
  20. data/lib/ferrum/network/exchange.rb +29 -2
  21. data/lib/ferrum/network/intercepted_request.rb +8 -17
  22. data/lib/ferrum/network/request.rb +23 -39
  23. data/lib/ferrum/network/request_params.rb +57 -0
  24. data/lib/ferrum/network/response.rb +25 -5
  25. data/lib/ferrum/network.rb +43 -16
  26. data/lib/ferrum/node.rb +21 -1
  27. data/lib/ferrum/page/frames.rb +5 -5
  28. data/lib/ferrum/page/screenshot.rb +42 -24
  29. data/lib/ferrum/page.rb +183 -131
  30. data/lib/ferrum/proxy.rb +1 -1
  31. data/lib/ferrum/target.rb +25 -5
  32. data/lib/ferrum/utils/elapsed_time.rb +0 -2
  33. data/lib/ferrum/utils/event.rb +19 -0
  34. data/lib/ferrum/utils/platform.rb +4 -0
  35. data/lib/ferrum/utils/thread.rb +18 -0
  36. data/lib/ferrum/version.rb +1 -1
  37. data/lib/ferrum.rb +3 -0
  38. metadata +14 -114
  39. data/lib/ferrum/browser/client.rb +0 -102
  40. data/lib/ferrum/browser/subscriber.rb +0 -36
data/lib/ferrum.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "concurrent-ruby"
4
+ require "ferrum/utils/event"
5
+ require "ferrum/utils/thread"
3
6
  require "ferrum/utils/platform"
4
7
  require "ferrum/utils/elapsed_time"
5
8
  require "ferrum/utils/attempt"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrum
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.13'
4
+ version: '0.15'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Vorotilin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-12 00:00:00.000000000 Z
11
+ date: 2024-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -55,121 +55,17 @@ dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: websocket-driver
57
57
  requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0.6'
62
- - - "<"
63
- - !ruby/object:Gem::Version
64
- version: '0.8'
65
- type: :runtime
66
- prerelease: false
67
- version_requirements: !ruby/object:Gem::Requirement
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- version: '0.6'
72
- - - "<"
73
- - !ruby/object:Gem::Version
74
- version: '0.8'
75
- - !ruby/object:Gem::Dependency
76
- name: chunky_png
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '1.3'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '1.3'
89
- - !ruby/object:Gem::Dependency
90
- name: image_size
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '2.0'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '2.0'
103
- - !ruby/object:Gem::Dependency
104
- name: pdf-reader
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '2.2'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
58
  requirements:
114
59
  - - "~>"
115
60
  - !ruby/object:Gem::Version
116
- version: '2.2'
117
- - !ruby/object:Gem::Dependency
118
- name: puma
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '4.1'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '4.1'
131
- - !ruby/object:Gem::Dependency
132
- name: rake
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '13.0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '13.0'
145
- - !ruby/object:Gem::Dependency
146
- name: rspec
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '3.8'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '3.8'
159
- - !ruby/object:Gem::Dependency
160
- name: sinatra
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '2.0'
166
- type: :development
61
+ version: '0.7'
62
+ type: :runtime
167
63
  prerelease: false
168
64
  version_requirements: !ruby/object:Gem::Requirement
169
65
  requirements:
170
66
  - - "~>"
171
67
  - !ruby/object:Gem::Version
172
- version: '2.0'
68
+ version: '0.7'
173
69
  description: Ferrum allows you to control headless Chrome browser
174
70
  email:
175
71
  - d.vorotilin@gmail.com
@@ -182,22 +78,23 @@ files:
182
78
  - lib/ferrum.rb
183
79
  - lib/ferrum/browser.rb
184
80
  - lib/ferrum/browser/binary.rb
185
- - lib/ferrum/browser/client.rb
186
81
  - lib/ferrum/browser/command.rb
187
82
  - lib/ferrum/browser/options.rb
188
83
  - lib/ferrum/browser/options/base.rb
189
84
  - lib/ferrum/browser/options/chrome.rb
190
85
  - lib/ferrum/browser/options/firefox.rb
191
86
  - lib/ferrum/browser/process.rb
192
- - lib/ferrum/browser/subscriber.rb
193
87
  - lib/ferrum/browser/version_info.rb
194
- - lib/ferrum/browser/web_socket.rb
195
88
  - lib/ferrum/browser/xvfb.rb
89
+ - lib/ferrum/client.rb
90
+ - lib/ferrum/client/subscriber.rb
91
+ - lib/ferrum/client/web_socket.rb
196
92
  - lib/ferrum/context.rb
197
93
  - lib/ferrum/contexts.rb
198
94
  - lib/ferrum/cookies.rb
199
95
  - lib/ferrum/cookies/cookie.rb
200
96
  - lib/ferrum/dialog.rb
97
+ - lib/ferrum/downloads.rb
201
98
  - lib/ferrum/errors.rb
202
99
  - lib/ferrum/frame.rb
203
100
  - lib/ferrum/frame/dom.rb
@@ -212,6 +109,7 @@ files:
212
109
  - lib/ferrum/network/exchange.rb
213
110
  - lib/ferrum/network/intercepted_request.rb
214
111
  - lib/ferrum/network/request.rb
112
+ - lib/ferrum/network/request_params.rb
215
113
  - lib/ferrum/network/response.rb
216
114
  - lib/ferrum/node.rb
217
115
  - lib/ferrum/page.rb
@@ -225,7 +123,9 @@ files:
225
123
  - lib/ferrum/target.rb
226
124
  - lib/ferrum/utils/attempt.rb
227
125
  - lib/ferrum/utils/elapsed_time.rb
126
+ - lib/ferrum/utils/event.rb
228
127
  - lib/ferrum/utils/platform.rb
128
+ - lib/ferrum/utils/thread.rb
229
129
  - lib/ferrum/version.rb
230
130
  homepage: https://github.com/rubycdp/ferrum
231
131
  licenses:
@@ -245,14 +145,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
245
145
  requirements:
246
146
  - - ">="
247
147
  - !ruby/object:Gem::Version
248
- version: 2.6.0
148
+ version: 2.7.0
249
149
  required_rubygems_version: !ruby/object:Gem::Requirement
250
150
  requirements:
251
151
  - - ">="
252
152
  - !ruby/object:Gem::Version
253
153
  version: '0'
254
154
  requirements: []
255
- rubygems_version: 3.3.7
155
+ rubygems_version: 3.5.6
256
156
  signing_key:
257
157
  specification_version: 4
258
158
  summary: Ruby headless Chrome driver
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "ferrum/browser/subscriber"
4
- require "ferrum/browser/web_socket"
5
-
6
- module Ferrum
7
- class Browser
8
- class Client
9
- INTERRUPTIONS = %w[Fetch.requestPaused Fetch.authRequired].freeze
10
-
11
- def initialize(ws_url, connectable, logger: nil, ws_max_receive_size: nil, id_starts_with: 0)
12
- @connectable = connectable
13
- @command_id = id_starts_with
14
- @pendings = Concurrent::Hash.new
15
- @ws = WebSocket.new(ws_url, ws_max_receive_size, logger)
16
- @subscriber, @interrupter = Subscriber.build(2)
17
-
18
- @thread = Thread.new do
19
- Thread.current.abort_on_exception = true
20
- Thread.current.report_on_exception = true if Thread.current.respond_to?(:report_on_exception=)
21
-
22
- loop do
23
- message = @ws.messages.pop
24
- break unless message
25
-
26
- if INTERRUPTIONS.include?(message["method"])
27
- @interrupter.async.call(message)
28
- elsif message.key?("method")
29
- @subscriber.async.call(message)
30
- else
31
- @pendings[message["id"]]&.set(message)
32
- end
33
- end
34
- end
35
- end
36
-
37
- def command(method, params = {})
38
- pending = Concurrent::IVar.new
39
- message = build_message(method, params)
40
- @pendings[message[:id]] = pending
41
- @ws.send_message(message)
42
- data = pending.value!(@connectable.timeout)
43
- @pendings.delete(message[:id])
44
-
45
- raise DeadBrowserError if data.nil? && @ws.messages.closed?
46
- raise TimeoutError unless data
47
-
48
- error, response = data.values_at("error", "result")
49
- raise_browser_error(error) if error
50
- response
51
- end
52
-
53
- def on(event, &block)
54
- case event
55
- when *INTERRUPTIONS
56
- @interrupter.on(event, &block)
57
- else
58
- @subscriber.on(event, &block)
59
- end
60
- end
61
-
62
- def subscribed?(event)
63
- [@interrupter, @subscriber].any? { |s| s.subscribed?(event) }
64
- end
65
-
66
- def close
67
- @ws.close
68
- # Give a thread some time to handle a tail of messages
69
- @pendings.clear
70
- @thread.kill unless @thread.join(1)
71
- end
72
-
73
- private
74
-
75
- def build_message(method, params)
76
- { method: method, params: params }.merge(id: next_command_id)
77
- end
78
-
79
- def next_command_id
80
- @command_id += 1
81
- end
82
-
83
- def raise_browser_error(error)
84
- case error["message"]
85
- # Node has disappeared while we were trying to get it
86
- when "No node with given id found",
87
- "Could not find node with given id"
88
- raise NodeNotFoundError, error
89
- # Context is lost, page is reloading
90
- when "Cannot find context with specified id"
91
- raise NoExecutionContextError, error
92
- when "No target with given id found"
93
- raise NoSuchPageError
94
- when /Could not compute content quads/
95
- raise CoordinatesNotFoundError
96
- else
97
- raise BrowserError, error
98
- end
99
- end
100
- end
101
- end
102
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ferrum
4
- class Browser
5
- class Subscriber
6
- include Concurrent::Async
7
-
8
- def self.build(size)
9
- (0..size).map { new }
10
- end
11
-
12
- def initialize
13
- super
14
- @on = Concurrent::Hash.new { |h, k| h[k] = Concurrent::Array.new }
15
- end
16
-
17
- def on(event, &block)
18
- @on[event] << block
19
- true
20
- end
21
-
22
- def subscribed?(event)
23
- @on.key?(event)
24
- end
25
-
26
- def call(message)
27
- method, params = message.values_at("method", "params")
28
- total = @on[method].size
29
- @on[method].each_with_index do |block, index|
30
- # In case of multiple callbacks we provide current index and total
31
- block.call(params, index, total)
32
- end
33
- end
34
- end
35
- end
36
- end