puppeteer-ruby 0.37.1 → 0.38.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -1
- data/README.md +1 -1
- data/docs/api_coverage.md +38 -34
- data/lib/puppeteer/cdp_session.rb +5 -0
- data/lib/puppeteer/dom_world.rb +9 -5
- data/lib/puppeteer/element_handle.rb +10 -8
- data/lib/puppeteer/executable_path_finder.rb +28 -0
- data/lib/puppeteer/frame.rb +31 -9
- data/lib/puppeteer/frame_manager.rb +138 -61
- data/lib/puppeteer/{request.rb → http_request.rb} +159 -22
- data/lib/puppeteer/{response.rb → http_response.rb} +2 -2
- data/lib/puppeteer/launcher/chrome.rb +26 -6
- data/lib/puppeteer/launcher/chrome_arg_options.rb +2 -1
- data/lib/puppeteer/launcher/firefox.rb +16 -6
- data/lib/puppeteer/lifecycle_watcher.rb +2 -2
- data/lib/puppeteer/network_manager.rb +10 -5
- data/lib/puppeteer/page/screenshot_options.rb +1 -1
- data/lib/puppeteer/page.rb +85 -22
- data/lib/puppeteer/puppeteer.rb +2 -0
- data/lib/puppeteer/target.rb +5 -0
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer/wait_task.rb +1 -1
- data/lib/puppeteer.rb +3 -2
- data/puppeteer-ruby.gemspec +1 -1
- metadata +7 -6
data/lib/puppeteer/page.rb
CHANGED
@@ -50,19 +50,26 @@ class Puppeteer::Page
|
|
50
50
|
@workers = {}
|
51
51
|
@user_drag_interception_enabled = false
|
52
52
|
|
53
|
-
@client.
|
54
|
-
if event['targetInfo']['type'] != 'worker'
|
53
|
+
@client.add_event_listener('Target.attachedToTarget') do |event|
|
54
|
+
if event['targetInfo']['type'] != 'worker' && event['targetInfo']['type'] != 'iframe'
|
55
55
|
# If we don't detach from service workers, they will never die.
|
56
|
+
# We still want to attach to workers for emitting events.
|
57
|
+
# We still want to attach to iframes so sessions may interact with them.
|
58
|
+
# We detach from all other types out of an abundance of caution.
|
59
|
+
# See https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/devtools_agent_host_impl.cc?ss=chromium&q=f:devtools%20-f:out%20%22::kTypePage%5B%5D%22
|
60
|
+
# for the complete list of available types.
|
56
61
|
@client.async_send_message('Target.detachFromTarget', sessionId: event['sessionId'])
|
57
62
|
next
|
58
63
|
end
|
59
64
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
if event['targetInfo']['type'] == 'worker'
|
66
|
+
session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
|
67
|
+
# const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
68
|
+
# this._workers.set(event.sessionId, worker);
|
69
|
+
# this.emit(PageEmittedEvents::WorkerCreated, worker);
|
70
|
+
end
|
64
71
|
end
|
65
|
-
@client.
|
72
|
+
@client.add_event_listener('Target.detachedFromTarget') do |event|
|
66
73
|
session_id = event['sessionId']
|
67
74
|
worker = @workers[session_id]
|
68
75
|
next unless worker
|
@@ -103,10 +110,10 @@ class Puppeteer::Page
|
|
103
110
|
@client.on_event('Page.loadEventFired') do |event|
|
104
111
|
emit_event(PageEmittedEvents::Load)
|
105
112
|
end
|
106
|
-
@client.
|
113
|
+
@client.add_event_listener('Runtime.consoleAPICalled') do |event|
|
107
114
|
handle_console_api(event)
|
108
115
|
end
|
109
|
-
@client.
|
116
|
+
@client.add_event_listener('Runtime.bindingCalled') do |event|
|
110
117
|
handle_binding_called(event)
|
111
118
|
end
|
112
119
|
@client.on_event('Page.javascriptDialogOpening') do |event|
|
@@ -153,6 +160,12 @@ class Puppeteer::Page
|
|
153
160
|
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
|
154
161
|
end
|
155
162
|
|
163
|
+
if event_name.to_s == 'request'
|
164
|
+
super('request') do |req|
|
165
|
+
req.enqueue_intercept_action(-> { block.call(req) })
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
156
169
|
super(event_name.to_s, &block)
|
157
170
|
end
|
158
171
|
|
@@ -512,7 +525,7 @@ class Puppeteer::Page
|
|
512
525
|
return
|
513
526
|
end
|
514
527
|
|
515
|
-
context = @frame_manager.execution_context_by_id(event['executionContextId'])
|
528
|
+
context = @frame_manager.execution_context_by_id(event['executionContextId'], @client)
|
516
529
|
values = event['args'].map do |arg|
|
517
530
|
remote_object = Puppeteer::RemoteObject.new(arg)
|
518
531
|
Puppeteer::JSHandle.create(context: context, remote_object: remote_object)
|
@@ -638,7 +651,7 @@ class Puppeteer::Page
|
|
638
651
|
|
639
652
|
# @param timeout [number|nil]
|
640
653
|
# @param wait_until [string|nil] 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
|
641
|
-
# @return [Puppeteer::
|
654
|
+
# @return [Puppeteer::HTTPResponse]
|
642
655
|
def reload(timeout: nil, wait_until: nil)
|
643
656
|
wait_for_navigation(timeout: timeout, wait_until: wait_until) do
|
644
657
|
@client.send_message('Page.reload')
|
@@ -658,28 +671,50 @@ class Puppeteer::Page
|
|
658
671
|
private def wait_for_network_manager_event(event_name, predicate:, timeout:)
|
659
672
|
option_timeout = timeout || @timeout_settings.timeout
|
660
673
|
|
661
|
-
|
662
|
-
|
674
|
+
promise = resolvable_future
|
675
|
+
|
676
|
+
listener_id = @frame_manager.network_manager.add_event_listener(event_name) do |event_target|
|
677
|
+
if predicate.call(event_target)
|
678
|
+
promise.fulfill(event_target)
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
begin
|
683
|
+
# Timeout.timeout(0) means "no limit" for timeout.
|
684
|
+
Timeout.timeout(option_timeout / 1000.0) do
|
685
|
+
await_any(promise, session_close_promise)
|
686
|
+
end
|
687
|
+
rescue Timeout::Error
|
688
|
+
raise Puppeteer::TimeoutError.new("waiting for #{event_name} failed: timeout #{option_timeout}ms exceeded")
|
689
|
+
ensure
|
663
690
|
@frame_manager.network_manager.remove_event_listener(listener_id)
|
664
691
|
end
|
692
|
+
end
|
693
|
+
|
694
|
+
private def wait_for_frame_manager_event(*event_names, predicate:, timeout:)
|
695
|
+
option_timeout = timeout || @timeout_settings.timeout
|
665
696
|
|
666
697
|
promise = resolvable_future
|
667
698
|
|
668
|
-
|
669
|
-
@frame_manager.
|
699
|
+
listener_ids = event_names.map do |event_name|
|
700
|
+
@frame_manager.add_event_listener(event_name) do |event_target|
|
670
701
|
if predicate.call(event_target)
|
671
|
-
promise.fulfill(
|
702
|
+
promise.fulfill(event_target) unless promise.resolved?
|
672
703
|
end
|
673
704
|
end
|
705
|
+
end
|
674
706
|
|
675
707
|
begin
|
708
|
+
# Timeout.timeout(0) means "no limit" for timeout.
|
676
709
|
Timeout.timeout(option_timeout / 1000.0) do
|
677
710
|
await_any(promise, session_close_promise)
|
678
711
|
end
|
679
712
|
rescue Timeout::Error
|
680
|
-
raise Puppeteer::TimeoutError.new("waiting for #{
|
713
|
+
raise Puppeteer::TimeoutError.new("waiting for #{event_names.join(" or ")} failed: timeout #{option_timeout}ms exceeded")
|
681
714
|
ensure
|
682
|
-
|
715
|
+
listener_ids.each do |listener_id|
|
716
|
+
@frame_manager.remove_event_listener(listener_id)
|
717
|
+
end
|
683
718
|
end
|
684
719
|
end
|
685
720
|
|
@@ -702,7 +737,7 @@ class Puppeteer::Page
|
|
702
737
|
if url
|
703
738
|
-> (request) { request.url == url }
|
704
739
|
else
|
705
|
-
|
740
|
+
predicate
|
706
741
|
end
|
707
742
|
|
708
743
|
wait_for_network_manager_event(NetworkManagerEmittedEvents::Request,
|
@@ -722,7 +757,7 @@ class Puppeteer::Page
|
|
722
757
|
# wait_for_request(predicate: -> (req){ req.url.start_with?('https://example.com/search') })
|
723
758
|
#
|
724
759
|
# @param url [String]
|
725
|
-
# @param predicate [Proc(Puppeteer::
|
760
|
+
# @param predicate [Proc(Puppeteer::HTTPRequest -> Boolean)]
|
726
761
|
define_async_method :async_wait_for_request
|
727
762
|
|
728
763
|
def wait_for_response(url: nil, predicate: nil, timeout: nil)
|
@@ -736,7 +771,7 @@ class Puppeteer::Page
|
|
736
771
|
if url
|
737
772
|
-> (response) { response.url == url }
|
738
773
|
else
|
739
|
-
|
774
|
+
predicate
|
740
775
|
end
|
741
776
|
|
742
777
|
wait_for_network_manager_event(NetworkManagerEmittedEvents::Response,
|
@@ -748,9 +783,37 @@ class Puppeteer::Page
|
|
748
783
|
# @!method async_wait_for_response(url: nil, predicate: nil, timeout: nil)
|
749
784
|
#
|
750
785
|
# @param url [String]
|
751
|
-
# @param predicate [Proc(Puppeteer::
|
786
|
+
# @param predicate [Proc(Puppeteer::HTTPRequest -> Boolean)]
|
752
787
|
define_async_method :async_wait_for_response
|
753
788
|
|
789
|
+
def wait_for_frame(url: nil, predicate: nil, timeout: nil)
|
790
|
+
if !url && !predicate
|
791
|
+
raise ArgumentError.new('url or predicate must be specified')
|
792
|
+
end
|
793
|
+
if predicate && !predicate.is_a?(Proc)
|
794
|
+
raise ArgumentError.new('predicate must be a proc.')
|
795
|
+
end
|
796
|
+
frame_predicate =
|
797
|
+
if url
|
798
|
+
-> (frame) { frame.url == url }
|
799
|
+
else
|
800
|
+
predicate
|
801
|
+
end
|
802
|
+
|
803
|
+
wait_for_frame_manager_event(
|
804
|
+
FrameManagerEmittedEvents::FrameAttached,
|
805
|
+
FrameManagerEmittedEvents::FrameNavigated,
|
806
|
+
predicate: frame_predicate,
|
807
|
+
timeout: timeout,
|
808
|
+
)
|
809
|
+
end
|
810
|
+
|
811
|
+
# @!method async_wait_for_frame(url: nil, predicate: nil, timeout: nil)
|
812
|
+
#
|
813
|
+
# @param url [String]
|
814
|
+
# @param predicate [Proc(Puppeteer::Frame -> Boolean)]
|
815
|
+
define_async_method :async_wait_for_frame
|
816
|
+
|
754
817
|
# @param timeout [number|nil]
|
755
818
|
# @param wait_until [string|nil] 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
|
756
819
|
def go_back(timeout: nil, wait_until: nil)
|
data/lib/puppeteer/puppeteer.rb
CHANGED
@@ -44,6 +44,7 @@ class Puppeteer::Puppeteer
|
|
44
44
|
args: nil,
|
45
45
|
user_data_dir: nil,
|
46
46
|
devtools: nil,
|
47
|
+
debugging_port: nil,
|
47
48
|
headless: nil,
|
48
49
|
ignore_https_errors: nil,
|
49
50
|
default_viewport: NoViewport.new,
|
@@ -63,6 +64,7 @@ class Puppeteer::Puppeteer
|
|
63
64
|
args: args,
|
64
65
|
user_data_dir: user_data_dir,
|
65
66
|
devtools: devtools,
|
67
|
+
debugging_port: debugging_port,
|
66
68
|
headless: headless,
|
67
69
|
ignore_https_errors: ignore_https_errors,
|
68
70
|
default_viewport: default_viewport,
|
data/lib/puppeteer/target.rb
CHANGED
data/lib/puppeteer/version.rb
CHANGED
data/lib/puppeteer/wait_task.rb
CHANGED
@@ -37,7 +37,7 @@ class Puppeteer::WaitTask
|
|
37
37
|
|
38
38
|
# Since page navigation requires us to re-install the pageScript, we should track
|
39
39
|
# timeout on our end.
|
40
|
-
if timeout
|
40
|
+
if timeout && timeout > 0
|
41
41
|
timeout_error = TimeoutError.new(title: title, timeout: timeout)
|
42
42
|
Concurrent::Promises.schedule(timeout / 1000.0) { terminate(timeout_error) unless @timeout_cleared }
|
43
43
|
end
|
data/lib/puppeteer.rb
CHANGED
@@ -33,10 +33,13 @@ require 'puppeteer/dialog'
|
|
33
33
|
require 'puppeteer/dom_world'
|
34
34
|
require 'puppeteer/emulation_manager'
|
35
35
|
require 'puppeteer/exception_details'
|
36
|
+
require 'puppeteer/executable_path_finder'
|
36
37
|
require 'puppeteer/execution_context'
|
37
38
|
require 'puppeteer/file_chooser'
|
38
39
|
require 'puppeteer/frame'
|
39
40
|
require 'puppeteer/frame_manager'
|
41
|
+
require 'puppeteer/http_request'
|
42
|
+
require 'puppeteer/http_response'
|
40
43
|
require 'puppeteer/js_coverage'
|
41
44
|
require 'puppeteer/js_handle'
|
42
45
|
require 'puppeteer/keyboard'
|
@@ -50,8 +53,6 @@ require 'puppeteer/protocol_stream_reader'
|
|
50
53
|
require 'puppeteer/puppeteer'
|
51
54
|
require 'puppeteer/query_handler_manager'
|
52
55
|
require 'puppeteer/remote_object'
|
53
|
-
require 'puppeteer/request'
|
54
|
-
require 'puppeteer/response'
|
55
56
|
require 'puppeteer/target'
|
56
57
|
require 'puppeteer/tracing'
|
57
58
|
require 'puppeteer/timeout_helper'
|
data/puppeteer-ruby.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency 'rollbar'
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.10.0 '
|
34
34
|
spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
|
35
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 1.23.0'
|
36
36
|
spec.add_development_dependency 'rubocop-rspec'
|
37
37
|
spec.add_development_dependency 'sinatra'
|
38
38
|
spec.add_development_dependency 'webrick'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppeteer-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.38.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
173
|
+
version: 1.23.0
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: 1.
|
180
|
+
version: 1.23.0
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rubocop-rspec
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,11 +282,14 @@ files:
|
|
282
282
|
- lib/puppeteer/event_callbackable.rb
|
283
283
|
- lib/puppeteer/events.rb
|
284
284
|
- lib/puppeteer/exception_details.rb
|
285
|
+
- lib/puppeteer/executable_path_finder.rb
|
285
286
|
- lib/puppeteer/execution_context.rb
|
286
287
|
- lib/puppeteer/file_chooser.rb
|
287
288
|
- lib/puppeteer/frame.rb
|
288
289
|
- lib/puppeteer/frame_manager.rb
|
289
290
|
- lib/puppeteer/geolocation.rb
|
291
|
+
- lib/puppeteer/http_request.rb
|
292
|
+
- lib/puppeteer/http_response.rb
|
290
293
|
- lib/puppeteer/if_present.rb
|
291
294
|
- lib/puppeteer/js_coverage.rb
|
292
295
|
- lib/puppeteer/js_handle.rb
|
@@ -313,8 +316,6 @@ files:
|
|
313
316
|
- lib/puppeteer/puppeteer.rb
|
314
317
|
- lib/puppeteer/query_handler_manager.rb
|
315
318
|
- lib/puppeteer/remote_object.rb
|
316
|
-
- lib/puppeteer/request.rb
|
317
|
-
- lib/puppeteer/response.rb
|
318
319
|
- lib/puppeteer/target.rb
|
319
320
|
- lib/puppeteer/timeout_helper.rb
|
320
321
|
- lib/puppeteer/timeout_settings.rb
|