Class: Puppeteer::LifecycleWatcher

Inherits:
Object
  • Object
show all
Includes:
IfPresent
Defined in:
lib/puppeteer/lifecycle_watcher.rb

Overview

Defined Under Namespace

Classes: ExpectedLifecycle, FrameDetachedError, TerminatedError

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from IfPresent

#if_present

Constructor Details

#initialize(frame_manager, frame, wait_until, timeout) ⇒ LifecycleWatcher

  • @param Puppeteer::LifecycleWatcher.!Puppeteer!Puppeteer.FrameManager frameManager

  • @param Puppeteer::LifecycleWatcher.!Puppeteer!Puppeteer.Frame frame

  • @param string|!Array<string> waitUntil

  • @param number timeout



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/puppeteer/lifecycle_watcher.rb', line 64

def initialize(frame_manager, frame, wait_until, timeout)
  @expected_lifecycle = ExpectedLifecycle.new(wait_until)
  @frame_manager = frame_manager
  @frame = frame
  @initial_loader_id = frame.loader_id
  @timeout = timeout

  @listener_ids = {}
  @listener_ids['client'] = @frame_manager.client.add_event_listener(CDPSessionEmittedEvents::Disconnected) do
    terminate(TerminatedError.new('Navigation failed because browser has disconnected!'))
  end
  @listener_ids['frame_manager'] = [
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::LifecycleEvent) do |_|
      check_lifecycle_complete
    end,
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigatedWithinDocument, &method(:navigated_within_document)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigated, &method(:navigated)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameSwapped, &method(:handle_frame_swapped)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameDetached, &method(:handle_frame_detached)),
  ]
  @listener_ids['network_manager'] = [
    @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Request, &method(:handle_request)),
    @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Response, &method(:handle_response)),
  ]

  @same_document_navigation_promise = resolvable_future
  @lifecycle_promise = resolvable_future
  @new_document_navigation_promise = resolvable_future
  @termination_promise = resolvable_future
  check_lifecycle_complete
end

Instance Attribute Details

#new_document_navigation_promiseObject (readonly)

Returns the value of attribute new_document_navigation_promise.



140
141
142
# File 'lib/puppeteer/lifecycle_watcher.rb', line 140

def new_document_navigation_promise
  @new_document_navigation_promise
end

#same_document_navigation_promiseObject (readonly)

Returns the value of attribute same_document_navigation_promise.



140
141
142
# File 'lib/puppeteer/lifecycle_watcher.rb', line 140

def same_document_navigation_promise
  @same_document_navigation_promise
end

Instance Method Details

#disposeObject



191
192
193
194
195
196
197
198
199
200
201
# File 'lib/puppeteer/lifecycle_watcher.rb', line 191

def dispose
  if_present(@listener_ids['client']) do |id|
    @frame_manager.client.remove_event_listener(id)
  end
  if_present(@listener_ids['frame_manager']) do |ids|
    @frame_manager.remove_event_listener(*ids)
  end
  if_present(@listener_ids['network_manager']) do |ids|
    @frame_manager.network_manager.remove_event_listener(*ids)
  end
end

#handle_frame_detached(frame) ⇒ Object

Parameters:



118
119
120
121
122
123
124
# File 'lib/puppeteer/lifecycle_watcher.rb', line 118

def handle_frame_detached(frame)
  if @frame == frame
    @termination_promise.reject(FrameDetachedError.new)
    return
  end
  check_lifecycle_complete
end

#handle_request(request) ⇒ Object

Parameters:



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/puppeteer/lifecycle_watcher.rb', line 97

def handle_request(request)
  return if request.frame != @frame || !request.navigation_request?
  @navigation_request = request
  # Resolve previous navigation response in case there are multiple
  # navigation requests reported by the backend. This generally should not
  # happen by it looks like it's possible.
  @navigation_response_received.fulfill(nil) if @navigation_response_received && !@navigation_response_received.resolved?
  @navigation_response_received = resolvable_future
  if request.response && !@navigation_response_received.resolved?
    @navigation_response_received.fulfill(nil)
  end
end

#handle_response(response) ⇒ Object

Parameters:



111
112
113
114
115
# File 'lib/puppeteer/lifecycle_watcher.rb', line 111

def handle_response(response)
  return if @navigation_request&.internal&.request_id  != response.request.internal.request_id

  @navigation_response_received.fulfill(nil) unless @navigation_response_received.resolved?
end


127
128
129
130
131
132
133
# File 'lib/puppeteer/lifecycle_watcher.rb', line 127

def navigation_response
  # Continue with a possibly null response.
  @navigation_response_received.value! rescue nil
  if_present(@navigation_request) do |request|
    request.response
  end
end

#timeout_or_termination_promiseObject



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/puppeteer/lifecycle_watcher.rb', line 146

def timeout_or_termination_promise
  if @timeout > 0
    future do
      Timeout.timeout(@timeout / 1000.0) do
        @termination_promise.value!
      end
    rescue Timeout::Error
      raise Puppeteer::TimeoutError.new("Navigation timeout of #{@timeout}ms exceeded")
    end
  else
    @termination_promise
  end
end