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.
@@ -50,19 +50,26 @@ class Puppeteer::Page
50
50
  @workers = {}
51
51
  @user_drag_interception_enabled = false
52
52
 
53
- @client.on_event('Target.attachedToTarget') do |event|
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
- session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
61
- # const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
62
- # this._workers.set(event.sessionId, worker);
63
- # this.emit(PageEmittedEvents::WorkerCreated, worker);
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.on_event('Target.detachedFromTarget') do |event|
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.on('Runtime.consoleAPICalled') do |event|
113
+ @client.add_event_listener('Runtime.consoleAPICalled') do |event|
107
114
  handle_console_api(event)
108
115
  end
109
- @client.on('Runtime.bindingCalled') do |event|
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::Response]
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
- @wait_for_network_manager_event_listener_ids ||= {}
662
- if_present(@wait_for_network_manager_event_listener_ids[event_name]) do |listener_id|
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
- @wait_for_network_manager_event_listener_ids[event_name] =
669
- @frame_manager.network_manager.add_event_listener(event_name) do |event_target|
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(nil)
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 #{event_name} failed: timeout #{timeout}ms exceeded")
713
+ raise Puppeteer::TimeoutError.new("waiting for #{event_names.join(" or ")} failed: timeout #{option_timeout}ms exceeded")
681
714
  ensure
682
- @frame_manager.network_manager.remove_event_listener(@wait_for_network_manager_event_listener_ids[event_name])
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
- -> (request) { predicate.call(request) }
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::Request -> Boolean)]
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
- -> (response) { predicate.call(response) }
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::Request -> Boolean)]
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)
@@ -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,
@@ -119,6 +119,11 @@ class Puppeteer::Target
119
119
  end
120
120
  end
121
121
 
122
+ # @internal
123
+ def raw_type
124
+ @target_info.type
125
+ end
126
+
122
127
  # @return {!Puppeteer.Browser}
123
128
  def browser
124
129
  @browser_context.browser
@@ -1,3 +1,3 @@
1
1
  module Puppeteer
2
- VERSION = '0.37.1'
2
+ VERSION = '0.38.0'
3
3
  end
@@ -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'
@@ -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.22.0'
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.37.1
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-10-26 00:00:00.000000000 Z
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.22.0
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.22.0
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